openapi: 3.0.3
info:
  title: Thredfi Accounting Platform API
  version: 1.0.0
  description: Comprehensive API for accounting, invoice management, open banking,
    and intelligence services.
paths:
  /api/ai-tools/{business_id}/account-details/:
    post:
      operationId: api_ai_tools_account_details_create
      description: Retrieve detailed information for a specific account.
      summary: Get account details
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountDetailsRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AccountDetailsRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AccountDetailsRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/ai-tools/{business_id}/disposal-history/:
    post:
      operationId: api_ai_tools_disposal_history_create
      description: Retrieve disposal history for assets.
      summary: Get disposal history
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DisposalHistoryRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/DisposalHistoryRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/DisposalHistoryRequest'
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/ai-tools/{business_id}/search-accounts/:
    post:
      operationId: api_ai_tools_search_accounts_create
      description: Search for accounts using keywords and optional filters.
      summary: Search accounts
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchAccountsRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/SearchAccountsRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/SearchAccountsRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/ai-tools/{business_id}/validate-accounts/:
    post:
      operationId: api_ai_tools_validate_accounts_create
      description: Validate a list of account codes.
      summary: Validate accounts
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ValidateAccountsRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ValidateAccountsRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ValidateAccountsRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: ''
  /api/schema/financial-admin/:
    get:
      operationId: api_schema_financial_admin_retrieve
      description: |-
        Custom Spectacular view that applies audience filtering.
        Set the 'audience' class attribute to filter by that audience.
      parameters:
      - in: query
        name: format
        schema:
          type: string
          enum:
          - json
          - yaml
      tags:
      - api
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          description: No response body
  /api/schema/partner/:
    get:
      operationId: api_schema_partner_retrieve
      description: |-
        Custom Spectacular view that applies audience filtering.
        Set the 'audience' class attribute to filter by that audience.
      parameters:
      - in: query
        name: format
        schema:
          type: string
          enum:
          - json
          - yaml
      tags:
      - api
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          description: No response body
  /api/v1/financial-admin-portal/auth/login/:
    post:
      operationId: api_v1_financial_admin_portal_auth_login_create
      description: Authenticate financial administrator and return JWT token
      summary: Financial portal login
      tags:
      - Financial Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FinancialPortalLoginRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FinancialPortalLoginRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FinancialPortalLoginRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinancialPortalToken'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/businesses/:
    get:
      operationId: api_v1_financial_admin_portal_businesses_list
      description: Returns all businesses assigned to this financial administrator's
        firm
      summary: List firm-assigned businesses
      parameters:
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      tags:
      - Financial Portal
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedFinancialBusinessListList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/businesses/{business_id}/:
    get:
      operationId: api_v1_financial_admin_portal_businesses_retrieve
      description: Returns detailed information about an assigned business
      summary: Get business details
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Financial Portal
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinancialBusinessDetail'
              examples:
                UKLimitedCompany:
                  value:
                    id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                    external_id: customer-123
                    legal_name: Acme Coffee Limited
                    name: Acme Coffee Ltd
                    entity_type: limited
                    phone_number: +44 20 1234 5678
                    tin: '1234567890'
                    vat_number: GB123456789
                    company_number: '12345678'
                    country: GB
                    province: Greater London
                    eu_nace_industry_code: '56.30'
                    email: accounting@acmecoffee.co.uk
                    base_currency: GBP
                    accounting_method: accrual
                    fiscal_year_end: '2024-03-31'
                    activation_at: '2024-01-15T10:30:00Z'
                    is_active: true
                    created_at: '2024-01-15T10:30:00Z'
                    updated_at: '2024-03-20T14:22:00Z'
                    metadata:
                      erp_id: ERP-12345
                      industry: hospitality
                  summary: UK Limited Company
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/businesses/{business_id}/tasks/:
    get:
      operationId: api_v1_financial_admin_portal_businesses_tasks_list
      description: Returns paginated list of tasks for an assigned business
      summary: List tasks for a business
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      tags:
      - Financial Portal
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedTaskListList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/businesses/{business_id}/tasks/{task_id}/:
    get:
      operationId: api_v1_financial_admin_portal_businesses_tasks_retrieve
      description: Returns detailed information about a task
      summary: Get task details
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Financial Portal
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskDetail'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/businesses/{business_id}/tasks/{task_id}/close/:
    post:
      operationId: financial_portal_close_task
      description: Close/approve a task. The authenticated financial admin is recorded
        as the closer.
      summary: Close task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Financial Portal
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskDetail'
              examples:
                TaskClosed:
                  value:
                    id: task-001-uuid-example
                    title: Review Q4 Financial Statements
                    description: Please review and approve the Q4 2025 financial statements.
                      All supporting documents have been uploaded to the shared folder.
                    status: pending_response
                    rejection_reason: null
                    due_date: '2026-02-15'
                    is_overdue: false
                    message_count: 5
                    created_by_name: John Smith
                    closed_by_name: null
                    closed_at: null
                    created_at: '2026-01-15T10:00:00Z'
                    updated_at: '2026-01-20T14:30:00Z'
                  summary: Task Closed
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/businesses/{business_id}/tasks/{task_id}/messages/:
    post:
      operationId: financial_portal_add_task_message
      description: Add a question to an existing task
      summary: Add message to task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Financial Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FinancialPortalTaskMessageCreateRequest'
            examples:
              AddQuestion:
                value:
                  message_type: question
                  message: Can you provide more details about this expense? The amount
                    doesn't match our records.
                summary: Add Question
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FinancialPortalTaskMessageCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FinancialPortalTaskMessageCreateRequest'
        required: true
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskMessageResponse'
              examples:
                MessageCreated:
                  value:
                    id: msg-001-uuid-example
                    message_type: question
                    message: Can you provide more details about this expense?
                    created_at: '2026-02-03T10:30:00Z'
                  summary: Message Created
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/businesses/{business_id}/tasks/{task_id}/update/:
    patch:
      operationId: financial_portal_update_task
      description: Update an existing task's fields
      summary: Update task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Financial Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedFinancialPortalTaskUpdateRequest'
            examples:
              UpdateTask:
                value:
                  title: Updated Task Title
                  description: Updated description with more details
                  due_date: '2026-02-20'
                  status: in_review
                summary: Update Task
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedFinancialPortalTaskUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedFinancialPortalTaskUpdateRequest'
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskDetail'
              examples:
                TaskUpdated:
                  value:
                    id: task-001-uuid-example
                    title: Review Q4 Financial Statements
                    description: Please review and approve the Q4 2025 financial statements.
                      All supporting documents have been uploaded to the shared folder.
                    status: pending_response
                    rejection_reason: null
                    due_date: '2026-02-15'
                    is_overdue: false
                    message_count: 5
                    created_by_name: John Smith
                    closed_by_name: null
                    closed_at: null
                    created_at: '2026-01-15T10:00:00Z'
                    updated_at: '2026-01-20T14:30:00Z'
                  summary: Task Updated
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/businesses/{business_id}/tasks/create/:
    post:
      operationId: financial_portal_create_task
      description: Create a new task with initial question. The authenticated financial
        admin is set as the creator.
      summary: Create task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Financial Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FinancialPortalTaskCreateRequest'
            examples:
              CreateTask:
                value:
                  title: Missing Receipt
                  first_question: Please provide the receipt for the $150 office supplies
                    charge from Jan 15
                  description: Need documentation for expense claim
                  due_date: '2026-02-15'
                summary: Create Task
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FinancialPortalTaskCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FinancialPortalTaskCreateRequest'
        required: true
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskDetail'
              examples:
                TaskCreated:
                  value:
                    id: task-001-uuid-example
                    title: Review Q4 Financial Statements
                    description: Please review and approve the Q4 2025 financial statements.
                      All supporting documents have been uploaded to the shared folder.
                    status: pending_response
                    rejection_reason: null
                    due_date: '2026-02-15'
                    is_overdue: false
                    message_count: 5
                    created_by_name: John Smith
                    closed_by_name: null
                    closed_at: null
                    created_at: '2026-01-15T10:00:00Z'
                    updated_at: '2026-01-20T14:30:00Z'
                  summary: Task Created
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/financial-admin-portal/dashboard/:
    get:
      operationId: api_v1_financial_admin_portal_dashboard_retrieve
      description: Returns paginated list of businesses with task metrics. Optimized
        to handle 50-100 businesses without N+1 queries.
      summary: Get dashboard overview
      tags:
      - Financial Portal
      security:
      - FinancialAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DashboardResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - financial-admin
  /api/v1/internal/auth/login/:
    post:
      operationId: api_v1_internal_auth_login_create
      description: Authenticate internal admin and return JWT token
      summary: Internal admin login
      tags:
      - Internal Admin
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InternalAdminLoginRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/InternalAdminLoginRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InternalAdminLoginRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalAdminToken'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /api/v1/internal/businesses/:
    get:
      operationId: api_v1_internal_businesses_list
      description: Returns all businesses across all partners
      summary: List all businesses
      parameters:
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      tags:
      - Internal Admin
      security:
      - InternalAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedInternalBusinessList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /api/v1/internal/partners/:
    get:
      operationId: api_v1_internal_partners_list
      description: Returns all partners in the system
      summary: List all partners
      parameters:
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      tags:
      - Internal Admin
      security:
      - InternalAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedInternalPartnerList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /api/v1/internal/partners/{partner_id}/menu-config/:
    get:
      operationId: get_partner_menu_config
      description: "\n        Retrieve the default menu configuration for a partner.\n\
        \n        This configuration serves as the default for all businesses under\
        \ this partner,\n        unless a business has its own override.\n\n     \
        \   Internal admin only.\n        "
      summary: Get partner menu configuration
      parameters:
      - in: path
        name: partner_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Internal Admin
      security:
      - InternalAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MenuConfig'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    put:
      operationId: update_partner_menu_config
      description: "\n        Update the default menu configuration for a partner.\n\
        \n        This will affect all businesses under this partner that do not have\n\
        \        their own business-specific overrides.\n\n        Businesses with\
        \ existing overrides will not be affected by this change.\n\n        Internal\
        \ admin only.\n        "
      summary: Update partner menu configuration
      parameters:
      - in: path
        name: partner_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Internal Admin
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateMenuConfigRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UpdateMenuConfigRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UpdateMenuConfigRequest'
        required: true
      security:
      - InternalAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MenuConfig'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    delete:
      operationId: api_v1_internal_partners_menu_config_destroy
      description: |-
        DELETE is not allowed for partner menu configuration.
        Partners must always have a default configuration.
      parameters:
      - in: path
        name: partner_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - api
      security:
      - InternalAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
  /api/v1/internal/system-health/:
    get:
      operationId: api_v1_internal_system_health_retrieve
      description: Returns system health metrics
      summary: System health check
      tags:
      - Internal Admin
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SystemHealth'
          description: ''
  /api/v1/internal/users/:
    get:
      operationId: api_v1_internal_users_list
      description: Returns all users in the system with their roles and associations
      summary: List all users
      parameters:
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      tags:
      - Internal Admin
      security:
      - InternalAdminAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedInternalUserList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /api/v1/partner-portal/analytics/:
    get:
      operationId: api_v1_partner_portal_analytics_retrieve
      description: Returns analytics for the partner's businesses
      summary: Get partner analytics
      tags:
      - Partner Portal
      security:
      - PartnerPortalAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerAnalytics'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /api/v1/partner-portal/api-keys/:
    get:
      operationId: api_v1_partner_portal_api_keys_retrieve
      description: Returns current API key (masked)
      summary: Get API key details
      tags:
      - Partner Portal
      security:
      - PartnerPortalAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerAPIKey'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /api/v1/partner-portal/api-keys/regenerate/:
    post:
      operationId: api_v1_partner_portal_api_keys_regenerate_create
      description: 'Regenerate partner API key. WARNING: This will invalidate the
        current API key'
      summary: Regenerate API key
      tags:
      - Partner Portal
      security:
      - PartnerPortalAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerAPIKeyRegenerate'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /api/v1/partner-portal/auth/login/:
    post:
      operationId: api_v1_partner_portal_auth_login_create
      description: Authenticate partner user and return JWT token
      summary: Partner portal login
      tags:
      - Partner Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerPortalLoginRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PartnerPortalLoginRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PartnerPortalLoginRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerPortalToken'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /api/v1/partner-portal/businesses/:
    get:
      operationId: api_v1_partner_portal_businesses_list
      description: Returns all businesses belonging to the partner
      summary: List partner's businesses
      parameters:
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      tags:
      - Partner Portal
      security:
      - PartnerPortalAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedPartnerBusinessListList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /api/v1/partner-portal/businesses/{business_id}/:
    get:
      operationId: api_v1_partner_portal_businesses_retrieve
      description: Returns detailed information about a specific business
      summary: Get business details
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Partner Portal
      security:
      - PartnerPortalAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerBusinessDetail'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /api/v1/product-pricing/inquiries/:
    post:
      operationId: create_pricing_inquiry
      description: Submit a pricing inquiry from an unregistered business. This creates
        a lead record for follow-up by the sales team. Returns 404 for invalid or
        inactive partners.
      summary: Submit pricing inquiry
      tags:
      - Product Pricing
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PricingInquiryCreateRequest'
            examples:
              PricingInquiryRequest:
                value:
                  partner_id: 987fcdeb-51a2-43d8-9f6e-123456789abc
                  business_name: Acme Corp
                  person_name: John Doe
                  email: john@acmecorp.com
                  phone: '+31612345678'
                  country_code: NL
                  selected_tier: tier_2
                  bookkeeping_included: true
                summary: Pricing Inquiry Request
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PricingInquiryCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PricingInquiryCreateRequest'
        required: true
      security:
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PricingInquiryResponse'
              examples:
                PricingInquiryResponse:
                  value:
                    id: 123e4567-e89b-12d3-a456-426614174000
                    status: pending
                    message: Your request has been received. We will contact you shortly.
                  summary: Pricing Inquiry Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
  /api/v1/product-pricing/tiers/:
    post:
      operationId: get_pricing_tiers
      description: Retrieve available pricing tiers for a partner. This is a public
        endpoint that validates the partner_id exists and is active. Returns 404 for
        invalid or inactive partners.
      summary: Get pricing tiers
      tags:
      - Product Pricing
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PricingTiersRequestRequest'
            examples:
              PricingTiersRequest:
                value:
                  partner_id: 987fcdeb-51a2-43d8-9f6e-123456789abc
                  business_name: Acme Corp
                summary: Pricing Tiers Request
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PricingTiersRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PricingTiersRequestRequest'
        required: true
      security:
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PricingTiersResponse'
              examples:
                PricingTiersResponse:
                  value:
                    currency: EUR
                    tiers:
                    - name: tier_1
                      display_order: 1
                      transactions_per_month: 25
                      price_cents: 1900
                      price_display: '19.00'
                    - name: tier_2
                      display_order: 2
                      transactions_per_month: 100
                      price_cents: 3900
                      price_display: '39.00'
                    - name: tier_3
                      display_order: 3
                      transactions_per_month: null
                      price_cents: 5900
                      price_display: '59.00'
                  summary: Pricing Tiers Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
  /bth/webhook/plaid/:
    post:
      operationId: plaid_webhook
      description: "\n        Receives webhook notifications from Plaid when transaction\
        \ data becomes available\n        or when other events occur. This endpoint\
        \ processes the webhook and triggers\n        appropriate background tasks\
        \ to sync transaction data.\n\n        **Supported Webhook Types:**\n    \
        \    - `TRANSACTIONS.INITIAL_UPDATE`: Transaction data is ready for a new\
        \ connection\n        - `TRANSACTIONS.DEFAULT_UPDATE`: New transactions are\
        \ available\n        - `TRANSACTIONS.HISTORICAL_UPDATE`: Historical transaction\
        \ data updated\n        - `ITEM.ERROR`: Item-level errors occurred\n     \
        \   - `ITEM.PENDING_EXPIRATION`: Access token expiring soon\n\n        **Security:**\
        \ This endpoint is configured to accept webhooks from Plaid's servers.\n \
        \       "
      summary: Plaid Webhook Endpoint
      tags:
      - Webhooks
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                webhook_type:
                  type: string
                  enum:
                  - TRANSACTIONS
                  - ITEM
                  - AUTH
                  - IDENTITY
                  description: Type of webhook event
                webhook_code:
                  type: string
                  enum:
                  - INITIAL_UPDATE
                  - DEFAULT_UPDATE
                  - HISTORICAL_UPDATE
                  - ERROR
                  - PENDING_EXPIRATION
                  description: Specific webhook event code
                item_id:
                  type: string
                  description: Plaid item ID that triggered the webhook
                error:
                  type: object
                  description: Error details (present for ERROR webhooks)
                  properties:
                    error_code:
                      type: string
                    error_message:
                      type: string
              required:
              - webhook_type
              - webhook_code
              - item_id
            examples:
              TransactionInitialUpdate:
                value:
                  webhook_type: TRANSACTIONS
                  webhook_code: INITIAL_UPDATE
                  item_id: eVBnVMp7zdTJLkRNr33Rs6zr7KNJqBFL9DrE6
                summary: Transaction Initial Update
                description: Webhook sent when transaction data becomes ready for
                  a new connection
              TransactionDefaultUpdate:
                value:
                  webhook_type: TRANSACTIONS
                  webhook_code: DEFAULT_UPDATE
                  item_id: eVBnVMp7zdTJLkRNr33Rs6zr7KNJqBFL9DrE6
                summary: Transaction Default Update
                description: Webhook sent when new transactions are available
              ItemError:
                value:
                  webhook_type: ITEM
                  webhook_code: ERROR
                  item_id: eVBnVMp7zdTJLkRNr33Rs6zr7KNJqBFL9DrE6
                  error:
                    error_code: ITEM_LOGIN_REQUIRED
                    error_message: the login details of this item have changed
                summary: Item Error
                description: Webhook sent when an item-level error occurs
      security:
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: string
              examples:
                TransactionInitialUpdate:
                  value:
                    webhook_type: TRANSACTIONS
                    webhook_code: INITIAL_UPDATE
                    item_id: eVBnVMp7zdTJLkRNr33Rs6zr7KNJqBFL9DrE6
                  summary: Transaction Initial Update
                  description: Webhook sent when transaction data becomes ready for
                    a new connection
                TransactionDefaultUpdate:
                  value:
                    webhook_type: TRANSACTIONS
                    webhook_code: DEFAULT_UPDATE
                    item_id: eVBnVMp7zdTJLkRNr33Rs6zr7KNJqBFL9DrE6
                  summary: Transaction Default Update
                  description: Webhook sent when new transactions are available
                ItemError:
                  value:
                    webhook_type: ITEM
                    webhook_code: ERROR
                    item_id: eVBnVMp7zdTJLkRNr33Rs6zr7KNJqBFL9DrE6
                    error:
                      error_code: ITEM_LOGIN_REQUIRED
                      error_message: the login details of this item have changed
                  summary: Item Error
                  description: Webhook sent when an item-level error occurs
                SuccessResponse:
                  value: OK
                  summary: Success Response
          description: Webhook processed successfully
        '400':
          content:
            application/json:
              schema:
                type: string
              examples:
                BadRequest:
                  value: Bad Request
                  summary: Bad Request
          description: Invalid JSON payload
        '500':
          content:
            application/json:
              schema:
                type: string
              examples:
                ServerError:
                  value: Internal Server Error
                  summary: Server Error
          description: Internal server error
  /portal/auth/csrf/:
    get:
      operationId: portal_auth_csrf_retrieve
      description: Obtain a CSRF token for cross-origin requests. The token is also
        set as a cookie in the response.
      summary: Get CSRF token
      tags:
      - Direct SME Portal
      security:
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  csrf_token:
                    type: string
          description: ''
  /portal/auth/login/:
    post:
      operationId: portal_auth_login_create
      description: Authenticate user with email and password. Creates a session and
        returns user details.
      summary: User login
      tags:
      - Direct SME Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
            examples:
              UserLoginRequest:
                value:
                  email: john.doe@example.com
                  password: SecurePassword123
                summary: User Login Request
                description: Example request payload for user login
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/LoginRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/LoginRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    $ref: '#/components/schemas/User'
              examples:
                UserLoginResponse:
                  value:
                    user:
                      id: 987fcdeb-51a2-43d8-9f6e-123456789abc
                      email: john.doe@example.com
                      first_name: John
                      last_name: Doe
                      user_type: partner_admin
                      is_active: true
                  summary: User Login Response
                  description: Example successful login response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /portal/auth/logout/:
    post:
      operationId: portal_auth_logout_create
      description: End the user's session and log them out.
      summary: User logout
      tags:
      - Direct SME Portal
      security:
      - DirectSMEPortalSessionAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /portal/auth/signup/:
    post:
      operationId: portal_auth_signup_create
      description: Create a new user account with auto-generated partner. Returns
        user details and partner information.
      summary: User signup
      tags:
      - Direct SME Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupRequest'
            examples:
              UserSignupRequest:
                value:
                  email: john.doe@example.com
                  password: SecurePassword123
                  first_name: John
                  last_name: Doe
                summary: User Signup Request
                description: Example request payload for user signup
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/SignupRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/SignupRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '201':
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    $ref: '#/components/schemas/User'
                  partner:
                    $ref: '#/components/schemas/Partner'
              examples:
                UserSignupResponse:
                  value:
                    user:
                      id: 987fcdeb-51a2-43d8-9f6e-123456789abc
                      email: john.doe@example.com
                      first_name: John
                      last_name: Doe
                      user_type: partner_admin
                      is_active: true
                    partner:
                      id: 987fcdeb-51a2-43d8-9f6e-123456789abc
                      name: John Doe's Partner
                      subdomain: direct-a1b2c3d4e5f6
                      industry: Multi-Industry
                      is_auto_generated: true
                      partner_type: direct_signup
                  summary: User Signup Response
                  description: Example successful signup response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /portal/businesses/:
    get:
      operationId: portal_businesses_list
      description: Get all businesses under the authenticated user's partner.
      summary: List businesses
      tags:
      - Direct SME Portal
      security:
      - DirectSMEPortalSessionAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DirectSMEBusiness'
              examples:
                BusinessListResponse:
                  value:
                  - - id: 123e4567-e89b-12d3-a456-426614174000
                      name: Acme Corporation
                      country: NL
                      base_currency: EUR
                      email: billing@acme.com
                      created_at: '2026-02-13T10:58:03.887570Z'
                      updated_at: '2026-02-13T10:58:03.887570Z'
                  summary: Business List Response
                  description: Example list of businesses
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /portal/businesses/{business_id}/token/:
    post:
      operationId: portal_businesses_token_create
      description: Generate a JWT token scoped to a specific business for SDK access.
        The business must belong to the authenticated user's partner.
      summary: Generate business token
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
        description: UUID of the business to generate token for
        required: true
      tags:
      - Direct SME Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectSMEBusinessTokenResponseRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/DirectSMEBusinessTokenResponseRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/DirectSMEBusinessTokenResponseRequest'
        required: true
      security:
      - DirectSMEPortalSessionAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectSMEBusinessTokenResponse'
              examples:
                BusinessTokenResponse:
                  value:
                    access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
                    expires_in: 3600
                    token_type: Bearer
                    business_id: 123e4567-e89b-12d3-a456-426614174000
                  summary: Business Token Response
                  description: Example JWT token response for SDK access
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /portal/businesses/create/:
    post:
      operationId: portal_businesses_create_create
      description: Create a new business under the authenticated user's partner.
      summary: Create business
      tags:
      - Direct SME Portal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectSMEBusinessCreateAPIRequest'
            examples:
              CreateBusinessRequest:
                value:
                  name: Acme Corporation
                  country: NL
                  base_currency: EUR
                  email: billing@acme.com
                summary: Create Business Request
                description: Example request payload for creating a business
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/DirectSMEBusinessCreateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/DirectSMEBusinessCreateAPIRequest'
        required: true
      security:
      - DirectSMEPortalSessionAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectSMEBusiness'
              examples:
                CreateBusinessResponse:
                  value:
                    id: 123e4567-e89b-12d3-a456-426614174000
                    name: Acme Corporation
                    country: NL
                    base_currency: EUR
                    email: billing@acme.com
                    created_at: '2026-02-13T10:58:03.887570Z'
                    updated_at: '2026-02-13T10:58:03.887570Z'
                  summary: Create Business Response
                  description: Example successful business creation response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/{business_id}/oauth2/token/:
    post:
      operationId: create_business_scoped_token
      description: Create a business-scoped JWT token for accessing business-specific
        endpoints. Requires a valid partner (unscoped) Bearer token in the Authorization
        header. Use the BearerUnscoped option in Swagger UI.
      summary: Create business-scoped access token
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Oauth2 authentication - Unscoped and Scoped
      security:
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BusinessTokenResponse'
              examples:
                BusinessTokenResponse:
                  value:
                    access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhMWIyYzNkNC01Njc4LTkwYWItY2RlZi0xMjM0NTY3ODkwYWIiLCJidXNpbmVzc19pZCI6IjNjOTBjM2NjLTBkNDQtNGI1MC04ODg4LThkZDI1NzM2MDUyYSIsImlhdCI6MTcwOTgyMTIwMCwiZXhwIjoxNzA5ODI0ODAwfQ.example
                    token_type: Bearer
                    expires_in: 3600
                    scope: business_access
                    business_id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                  summary: Business Token Response
          description: ''
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2ErrorResponse'
          description: ''
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2ErrorResponse'
          description: ''
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2ErrorResponse'
          description: ''
      x-audience:
      - partner
  /v1/platform/accounting-periods/:
    get:
      operationId: list_accounting_periods
      description: "\n        Returns a list of accounting periods for a business\
        \ with optional filtering.\n\n        **Filtering**: Support for year, month,\
        \ and status filters\n        **Statuses**: open, soft_closed, hard_closed,\
        \ audited\n        "
      summary: List accounting periods
      parameters:
      - in: query
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business ID (required)
        required: true
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: status
        schema:
          type: string
        description: 'Filter by status: open, soft_closed, hard_closed, audited'
      - in: query
        name: year
        schema:
          type: integer
        description: Filter by year (e.g., 2024)
      tags:
      - Accounting Periods
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedAccountingPeriodList'
          description: ''
    post:
      operationId: create_accounting_period
      description: "\n        Create a new accounting period for a business.\n\n \
        \       **Idempotency**: Returns existing period if one already exists for\
        \ the specified year/month.\n        **Required Fields**: business_id, year,\
        \ month\n        "
      summary: Create accounting period
      tags:
      - Accounting Periods
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PeriodCreateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PeriodCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PeriodCreateRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountingPeriod'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/accounting-periods/{period_id}/:
    get:
      operationId: v1_platform_accounting_periods_retrieve
      description: |-
        ViewSet for Accounting Period operations.

        Provides:
        - List: GET /accounting-periods/
        - Create: POST /accounting-periods/
        - Close: POST /accounting-periods/{period_id}/close/
        - Reopen: POST /accounting-periods/{period_id}/reopen/
        - Checklist: GET /accounting-periods/{period_id}/close-checklist/
      parameters:
      - in: path
        name: period_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this accounting period.
        required: true
      tags:
      - v1
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountingPeriod'
          description: ''
  /v1/platform/accounting-periods/{period_id}/close/:
    post:
      operationId: close_accounting_period
      description: "\n        Close an accounting period with optional close level\
        \ (soft, hard, audited).\n\n        **Advisory Checklist**: Returns checklist\
        \ with warnings/issues but does not block closing.\n        **Close Levels**:\n\
        \        - soft_closed: Allows changes with warning\n        - hard_closed:\
        \ Prevents changes (default)\n        - audited: Immutable period\n      \
        \  "
      summary: Close accounting period
      parameters:
      - in: path
        name: period_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this accounting period.
        required: true
      tags:
      - Accounting Periods
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PeriodCloseRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PeriodCloseRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PeriodCloseRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PeriodCloseResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/accounting-periods/{period_id}/close-checklist/:
    get:
      operationId: get_period_close_checklist
      description: "\n        Preview the advisory checklist before closing a period.\n\
        \n        **Advisory Only**: Checklist identifies potential issues but does\
        \ not block closing.\n        **14 Checks**: Covers reconciliation, sub-ledger\
        \ to GL, journal entries, and general validation.\n        "
      summary: Get advisory close checklist
      parameters:
      - in: path
        name: period_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this accounting period.
        required: true
      tags:
      - Accounting Periods
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PeriodCloseChecklist'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/accounting-periods/{period_id}/reopen/:
    post:
      operationId: reopen_accounting_period
      description: "\n        Reopen a closed accounting period (always allowed -\
        \ no restrictions).\n\n        **Note**: This sets the period status back\
        \ to 'open' regardless of previous status.\n        "
      summary: Reopen accounting period
      parameters:
      - in: path
        name: period_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this accounting period.
        required: true
      tags:
      - Accounting Periods
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PeriodReopenRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PeriodReopenRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PeriodReopenRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PeriodReopenResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/accounting-periods/bulk-close/:
    post:
      operationId: v1_platform_accounting_periods_bulk_close_create
      description: |-
        Bulk close multiple periods at once.

        Supports three ways to specify periods:
        1. Explicit list: periods=["2024-01", "2024-02", "2024-03"]
        2. Full year: year=2024 (all 12 months)
        3. Date range: start_period="2024-01", end_period="2024-06"
      tags:
      - v1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountingPeriodRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AccountingPeriodRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AccountingPeriodRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountingPeriod'
          description: ''
  /v1/platform/accounting-periods/bulk-reopen/:
    post:
      operationId: v1_platform_accounting_periods_bulk_reopen_create
      description: |-
        Bulk reopen multiple periods at once.

        Supports same period specification options as bulk-close.
      tags:
      - v1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountingPeriodRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AccountingPeriodRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AccountingPeriodRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountingPeriod'
          description: ''
  /v1/platform/businesses/:
    get:
      operationId: list_businesses
      description: "\n        Returns a list of all active businesses registered in\
        \ our platform by the partner with standardized pagination.\n\n        **Supported\
        \ Countries**: EU/UK, Nordic, and APAC markets\n        - EU/UK/Nordic: GB,\
        \ DE, FR, NL, ES, IT, IE, BE, AT, PT, SE, NO, DK, FI, IS\n        - APAC:\
        \ MY, SG\n\n        **Supported Currencies**: GBP, EUR, USD, SEK, NOK, DKK,\
        \ ISK, MYR, SGD\n        "
      summary: List businesses
      parameters:
      - in: query
        name: country
        schema:
          type: string
        description: Filter by country code (case-insensitive, e.g., GB, DE, FR, MY,
          SG)
      - in: query
        name: entity_type
        schema:
          type: string
        description: 'Filter by entity type (case-insensitive). Valid values depend
          on business country. Examples: limited, gmbh, bv, sl, etc.'
      - in: query
        name: is_archived
        schema:
          type: boolean
        description: Filter by archived status (true/false)
      - in: query
        name: legal_name
        schema:
          type: string
        description: Filter by legal name (case-insensitive partial match)
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: search
        schema:
          type: string
        description: Search in business name, legal name, external ID, VAT number,
          and company number
      tags:
      - Business Management
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedBusinessListList'
              examples:
                UKLimitedCompany:
                  value:
                    count: 123
                    page_info:
                      total_count: 123
                      current_page: 1
                      total_pages: 7
                      page_size: 20
                    results:
                    - id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                      external_id: customer-123
                      name: Acme Coffee Ltd
                      legal_name: Acme Coffee Limited
                      entity_type: limited
                      country: GB
                      province: Greater London
                      eu_nace_industry_code: '56.30'
                      is_active: true
                      activation_at: '2024-01-15T10:30:00Z'
                      created_at: '2024-01-15T10:30:00Z'
                      updated_at: '2024-03-20T14:22:00Z'
                      vat_number: GB123456789
                      company_number: '12345678'
                      tax_id: '1234567890'
                      base_currency: GBP
                  summary: UK Limited Company
          description: ''
      x-audience:
      - partner
    post:
      operationId: create_business
      description: "\n        Create a new business with idempotency support via external_id.\n\
        \n        **Supported Markets**: EU/UK, Nordic, and APAC countries (GB, DE,\
        \ FR, NL, ES, BE, IT, IE, AT, PT, SE, NO, DK, FI, IS, MY, SG)\n\n        **Entity\
        \ Type Validation**:\n        - **GB, DE, NL, ES, BE, MY, SG**: Must use country-specific\
        \ entity types (see documentation)\n        - **All other countries**: Any\
        \ entity type string is accepted\n\n        **Idempotency**: If a business\
        \ with the same external_id already exists for your partner,\n        this\
        \ endpoint will return the existing business (HTTP 200) instead of creating\
        \ a duplicate.\n\n        **Response Metadata**: Includes `_meta` field indicating\
        \ creation vs idempotent return.\n\n        **Required Fields**: external_id,\
        \ legal_name, entity_type, email\n        "
      summary: Create business (idempotent)
      tags:
      - Business Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBusinessRequest'
            examples:
              UKLimitedCompany:
                value:
                  external_id: customer-123
                  legal_name: Acme Coffee Limited
                  entity_type: limited
                  email: accounting@acmecoffee.co.uk
                  country: GB
                  base_currency: GBP
                  phone_number: +44 20 1234 5678
                  vat_number: GB123456789
                  company_number: '12345678'
                  province: Greater London
                  accounting_method: accrual
                  fiscal_year_end: '2024-03-31'
                  metadata:
                    erp_id: ERP-12345
                    industry: hospitality
                summary: UK Limited Company
              GermanGmbH:
                value:
                  external_id: de-company-456
                  legal_name: Mustermann Consulting GmbH
                  entity_type: gmbh
                  email: info@mustermann.de
                  country: DE
                  base_currency: EUR
                  vat_number: DE123456789
                  tin: 12/345/67890
                  accounting_method: accrual
                summary: German GmbH
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateBusinessRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateBusinessRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Business'
              examples:
                UKLimitedCompany:
                  value:
                    id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                    external_id: customer-123
                    legal_name: Acme Coffee Limited
                    name: Acme Coffee Ltd
                    entity_type: limited
                    phone_number: +44 20 1234 5678
                    tin: '1234567890'
                    vat_number: GB123456789
                    company_number: '12345678'
                    country: GB
                    province: Greater London
                    eu_nace_industry_code: '56.30'
                    email: accounting@acmecoffee.co.uk
                    base_currency: GBP
                    accounting_method: accrual
                    fiscal_year_end: '2024-03-31'
                    activation_at: '2024-01-15T10:30:00Z'
                    is_active: true
                    created_at: '2024-01-15T10:30:00Z'
                    updated_at: '2024-03-20T14:22:00Z'
                    metadata:
                      erp_id: ERP-12345
                      industry: hospitality
                  summary: UK Limited Company
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/:
    get:
      operationId: get_business
      description: Retrieve details of a specific business
      summary: Get business
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this business.
        required: true
      tags:
      - Business Management
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Business'
              examples:
                UKLimitedCompany:
                  value:
                    id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                    external_id: customer-123
                    legal_name: Acme Coffee Limited
                    name: Acme Coffee Ltd
                    entity_type: limited
                    phone_number: +44 20 1234 5678
                    tin: '1234567890'
                    vat_number: GB123456789
                    company_number: '12345678'
                    country: GB
                    province: Greater London
                    eu_nace_industry_code: '56.30'
                    email: accounting@acmecoffee.co.uk
                    base_currency: GBP
                    accounting_method: accrual
                    fiscal_year_end: '2024-03-31'
                    activation_at: '2024-01-15T10:30:00Z'
                    is_active: true
                    created_at: '2024-01-15T10:30:00Z'
                    updated_at: '2024-03-20T14:22:00Z'
                    metadata:
                      erp_id: ERP-12345
                      industry: hospitality
                  summary: UK Limited Company
          description: ''
      x-audience:
      - partner
    patch:
      operationId: update_business
      description: Partial update of business fields
      summary: Update business
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this business.
        required: true
      tags:
      - Business Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedUpdateBusinessRequest'
            examples:
              UpdateEmailAndPhone:
                value:
                  email: newemail@acmecoffee.co.uk
                  phone_number: +44 20 9876 5432
                summary: Update Email and Phone
              UpdateVATNumber:
                value:
                  vat_number: GB987654321
                  company_number: '87654321'
                summary: Update VAT Number
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedUpdateBusinessRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedUpdateBusinessRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateBusiness'
          description: ''
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/ap-documents/upload:
    post:
      operationId: upload_ap_document
      description: "\n        Upload an accounts payable document (vendor invoice,\
        \ credit note, or receipt) for automated processing.\n\n        **Processing\
        \ Flow:**\n        1. File is uploaded to S3 storage\n        2. Background\
        \ LangGraph workflow is queued\n        3. API returns immediately (202 Accepted)\n\
        \        4. Background processing:\n           - Downloads file and calculates\
        \ content hash\n           - Quick duplicate check (exact file match)\n  \
        \         - Extracts data using Reducto AI\n           - Classifies document\
        \ type (invoice/credit_note/receipt)\n           - Validates document is for\
        \ this company\n           - Routes to type-specific workflow:\n         \
        \    * **Invoice**: Creates/matches vendor, checks duplicates, creates Bill\n\
        \             * **Credit Note**: Creates VendorCreditNote\n             *\
        \ **Receipt**: Matches to Bill, updates payment status\n        5. Processed\
        \ document appears in GET /bills/ or relevant endpoint\n\n        **File Requirements:**\n\
        \        - Format: PDF or images (PNG, JPEG, GIF, BMP, TIFF, HEIC)\n     \
        \   - Size: Maximum 50MB for PDF, 10-20MB for images\n        - Content: Vendor\
        \ invoice, credit note, or receipt\n        - Content-Type validation: File\
        \ content is verified to match declared type\n\n        **Document Classification:**\n\
        \        - AI determines if document is invoice, credit note, or receipt\n\
        \        - Invoice: Bill created, vendor matched/created\n        - Credit\
        \ Note: VendorCreditNote created\n        - Receipt: Matched to existing Bill\
        \ if possible\n\n        **Vendor Matching (for invoices):**\n        - AI\
        \ semantic matching (handles \"Amazon Inc\" vs \"Amazon.com\")\n        -\
        \ VAT number matching (very strong signal)\n        - Creates new vendor if\
        \ no confident match found\n\n        **Duplicate Detection:**\n        -\
        \ File hash check (exact file duplicate)\n        - AI semantic duplicate\
        \ check (same invoice number, date, amount)\n        - High confidence duplicates\
        \ (≥90%) flagged for review\n        - Medium confidence (70-89%) flagged\
        \ for review\n\n        **Company Validation:**\n        - Invoices/Credit\
        \ Notes: Strict validation (must match company name/VAT)\n        - Receipts:\
        \ Lenient validation (assumes for company unless explicitly different)\n \
        \       - Documents not for this company are flagged for review\n\n      \
        \  **Review Flags:**\n        Documents may be flagged for manual review if:\n\
        \        - Duplicate detected (file or semantic)\n        - Not for this company\n\
        \        - Low extraction confidence\n        - Uncertain document type classification\n\
        \        - Line items don't match total\n\n        **Access Control:**\n \
        \       - Requires partner authentication\n        - Business must belong\
        \ to authenticated partner\n        "
      summary: Upload AP Document for AI Processing
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Accounts Payable
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/APDocumentUploadRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/APDocumentUploadRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/APDocumentUploadRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APDocumentUploadResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/ap/stats/:
    get:
      operationId: get_ap_stats
      description: "\n        Retrieve statistics for all Accounts Payable entities\
        \ grouped by status.\n\n        Returns counts for:\n        - **Bills**:\
        \ all, unpaid (received + partially_paid), paid\n        - **Vendor Credits**:\
        \ all, unapplied, applied\n        - **Vendor Refunds**: all, pending (to\
        \ get non-pending, use list endpoint with status filter)\n        - **Receipts**:\
        \ all, breakdown by payment method\n\n        **Note**: For vendor refunds,\
        \ \"pending\" only includes status=pending. To filter by other\n        statuses\
        \ (partially_allocated, allocated, completed, cancelled), use the vendor-refunds\n\
        \        list endpoint with the status query parameter.\n\n        This endpoint\
        \ is optimized for efficient counting (5 queries total).\n        "
      summary: Get accounts payable statistics
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - Accounts Payable
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/APStats'
              examples:
                APStatsResponse:
                  value:
                  - bills:
                      all: 19
                      unpaid: 8
                      paid: 11
                    vendor_credits:
                      all: 4
                      unapplied: 2
                      applied: 2
                    vendor_refunds:
                      all: 6
                      pending: 5
                    receipts:
                      all: 3
                      payment_method:
                        cash: 1
                        credit_card: 1
                        debit_card: 0
                        bank_transfer: 0
                        check: 1
                        other: 0
                  summary: AP Stats Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/ar-documents/upload:
    post:
      operationId: invoice_upload_ar_invoice_pdf
      description: "\n        Upload an invoice PDF file for automated AI-powered\
        \ extraction and processing.\n\n        **Processing Flow:**\n        1. PDF\
        \ is uploaded to S3 storage\n        2. Background LangGraph workflow is queued\
        \ for intelligent processing\n        3. API returns immediately (202 Accepted)\n\
        \        4. Background workflow processing:\n           - Extracts invoice\
        \ data using Reducto AI\n           - Classifies document type (invoice/credit\
        \ note)\n           - Validates document is from your business\n         \
        \  - Matches or creates customer using AI semantic matching\n           -\
        \ Detects semantic duplicates\n           - Validates extracted data\n   \
        \        - Creates invoice record\n        5. Extracted invoice appears in\
        \ GET /invoices/ list\n\n        **File Requirements:**\n        - Format:\
        \ PDF or images (PNG, JPEG, GIF, BMP, TIFF, HEIC)\n        - Size: Maximum\
        \ 50MB for PDF, 10-20MB for images\n        - Content: Invoice document or\
        \ scanned invoice image\n        - Content-Type validation: File content is\
        \ verified to match declared type\n\n        **Extraction Quality:**\n   \
        \     - Fields with ≥90% confidence are auto-filled\n        - Fields below\
        \ threshold require manual review\n        - Line items with parsing errors\
        \ are flagged\n        - Total mismatches (>1% or >$10) trigger review flag\n\
        \n        **Duplicate Detection:**\n        - AI compares with last 100 invoices\n\
        \        - High confidence duplicates (≥90%) are blocked\n        - Medium\
        \ confidence (70-89%) are flagged for review\n        - Low confidence (<70%)\
        \ are processed normally\n\n        **Access Control:**\n        - Requires\
        \ partner authentication\n        - Business must belong to authenticated\
        \ partner\n        "
      summary: Upload Invoice PDF for AI Extraction
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Invoices
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceUploadRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/InvoiceUploadRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InvoiceUploadRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoiceUploadResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/ar/stats/:
    get:
      operationId: get_ar_stats
      description: "\n        Retrieve statistics for all Accounts Receivable entities\
        \ grouped by status.\n\n        Returns counts for:\n        - **Invoices**:\
        \ all, unpaid (draft, issued, sent, partially_paid, partially_written_off),\
        \ paid\n        - **Refunds**: all, processed (paid)\n        - **Credit Notes**:\
        \ all, draft (draft, sent, partially_applied), applied\n\n        This endpoint\
        \ is optimized for efficient counting.\n        "
      summary: Get accounts receivable statistics
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - Accounts Receivable
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ARStats'
              examples:
                ARStatsResponse:
                  value:
                  - invoices:
                      all: 13
                      unpaid: 11
                      paid: 2
                    refunds:
                      all: 3
                      processed: 3
                    credit_notes:
                      all: 5
                      draft: 1
                      applied: 4
                  summary: AR Stats Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/archive/:
    post:
      operationId: archive_business
      description: Archive a business
      summary: Archive business
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this business.
        required: true
      tags:
      - Business Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BusinessRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/BusinessRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BusinessRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Business'
              examples:
                UKLimitedCompany:
                  value:
                    id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                    external_id: customer-123
                    legal_name: Acme Coffee Limited
                    name: Acme Coffee Ltd
                    entity_type: limited
                    phone_number: +44 20 1234 5678
                    tin: '1234567890'
                    vat_number: GB123456789
                    company_number: '12345678'
                    country: GB
                    province: Greater London
                    eu_nace_industry_code: '56.30'
                    email: accounting@acmecoffee.co.uk
                    base_currency: GBP
                    accounting_method: accrual
                    fiscal_year_end: '2024-03-31'
                    activation_at: '2024-01-15T10:30:00Z'
                    is_active: true
                    created_at: '2024-01-15T10:30:00Z'
                    updated_at: '2024-03-20T14:22:00Z'
                    metadata:
                      erp_id: ERP-12345
                      industry: hospitality
                  summary: UK Limited Company
          description: ''
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bank-accounts/:
    get:
      operationId: list_bank_accounts
      description: "\n        Retrieve a paginated list of bank account connections\
        \ with advanced filtering options and statistics.\n\n        **Default Behavior:**\n\
        \        - Returns all bank account connections for the authenticated partner's\
        \ businesses\n        - Uses summary serializer for list view (lighter payload)\n\
        \        - Includes statistics for the filtered results\n\n        **Statistics\
        \ Included:**\n        - Total account counts (total, active, inactive)\n\
        \        - Sync status counts (synced, never synced)\n        - Mapping status\
        \ counts (mapped, unmapped)\n        - Provider breakdown\n        - Currency\
        \ breakdown\n        - Balance summary (total, average, min, max, account\
        \ counts)\n\n        **Filtering Options:**\n\n        **Status Filters:**\n\
        \        - `is_active`: Filter by active status (true/false)\n\n        **Provider\
        \ & Business Filters:**\n        - `provider`: Filter by provider (e.g., 'plaid')\n\
        \        - `bank_link_status`: Filter by bank link status\n        - `business_id`:\
        \ Filter by specific business UUID\n        - `business_name`: Search business\
        \ names\n\n        **Account Filters:**\n        - `currency`: Filter by currency\
        \ code (USD, EUR, etc.)\n        - `balance_min`: Minimum balance filter\n\
        \        - `balance_max`: Maximum balance filter\n        - `has_mapped_account`:\
        \ Filter by whether account is mapped to chart of accounts\n        - `mapped_account_id`:\
        \ Filter by specific mapped account ID\n\n        **Date Filters:**\n    \
        \    - `updated_after`: Accounts updated after date\n        - `updated_before`:\
        \ Accounts updated before date\n        - `first_sync_after`: Accounts first\
        \ synced after date\n        - `first_sync_before`: Accounts first synced\
        \ before date\n        - `has_been_synced`: Filter by whether account has\
        \ been synced\n\n        **Search:**\n        - `search`: Search across account\
        \ names, keys, masks, and business names\n\n        **Ordering:**\n      \
        \  - `ordering`: Order by any field (prefix with '-' for descending)\n   \
        \     - Default: `-created_at` (newest first)\n\n        **Examples:**\n \
        \       - Get all active accounts: `?is_active=true`\n        - Get accounts\
        \ for specific business: `?business_id=123e4567-e89b-12d3-a456-426614174000`\n\
        \        - Get accounts that have been synced: `?has_been_synced=true`\n \
        \       - Get mapped accounts: `?has_mapped_account=true`\n        - Search\
        \ for accounts: `?search=checking`\n        - Order by balance: `?ordering=-balance`\n\
        \        "
      summary: List Bank Account Connections
      parameters:
      - in: query
        name: account_key
        schema:
          type: string
        description: Filter by account key (partial match)
      - in: query
        name: balance_max
        schema:
          type: number
          format: double
        description: Filter by maximum balance
      - in: query
        name: balance_min
        schema:
          type: number
          format: double
        description: Filter by minimum balance
      - in: query
        name: bank_link_status
        schema:
          type: string
          enum:
          - active
          - error
          - revoked
        description: Filter by bank link status
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - in: query
        name: business_id
        schema:
          type: string
        description: Filter by business ID (UUID format)
      - in: query
        name: business_name
        schema:
          type: string
        description: Filter by business name (partial match)
      - in: query
        name: currency
        schema:
          type: string
        description: Filter by currency code (USD, EUR, etc.)
      - in: query
        name: display_name
        schema:
          type: string
        description: Filter by display name (exact, case-insensitive)
      - in: query
        name: first_sync_after
        schema:
          type: string
          format: date-time
        description: Filter accounts first synced after this date
      - in: query
        name: first_sync_before
        schema:
          type: string
          format: date-time
        description: Filter accounts first synced before this date
      - in: query
        name: has_been_synced
        schema:
          type: boolean
        description: Filter by whether account has been synced (true for synced, false
          for never synced)
      - in: query
        name: has_mapped_account
        schema:
          type: boolean
        description: Filter by whether account is mapped (true for mapped, false for
          unmapped)
      - in: query
        name: is_active
        schema:
          type: boolean
        description: Filter by active status
      - in: query
        name: mapped_account
        schema:
          type: string
          format: uuid
      - in: query
        name: mapped_account_id
        schema:
          type: string
          format: uuid
        description: Filter by mapped account ID
      - in: query
        name: ordering
        schema:
          type: string
        description: Order by field (prefix with - for descending)
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - in: query
        name: provider
        schema:
          type: string
        description: Filter by provider (e.g., plaid)
      - in: query
        name: search
        schema:
          type: string
        description: Search in account names, keys, masks, and business names
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: Filter accounts updated after this date
      - in: query
        name: updated_before
        schema:
          type: string
          format: date-time
        description: Filter accounts updated before this date
      tags:
      - Bank Accounts Management
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedBankAccountConnectionSummaryList'
              examples:
                UKBusinessBankAccountList(Summary):
                  value:
                    count: 123
                    page_info:
                      total_count: 123
                      current_page: 1
                      total_pages: 7
                      page_size: 20
                    results:
                    - id: 9f90c3cc-6i00-0h16-eeee-eii81402618g
                      display_name: Barclays Business Current Account
                      official_name: Barclays Bank PLC - Business Account
                      mask: '1234'
                      balance: 12500.5
                      balance_cents: 1250050
                      currency: GBP
                      is_active: true
                      bank_link_status: active
                      business_name: The Red Lion Pub Ltd
                      provider: plaid
                      created_at: '2024-01-15T10:30:00Z'
                  summary: UK Business Bank Account List (Summary)
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-accounts/{bank_account_id}/:
    get:
      operationId: retrieve_bank_account
      description: "\n        Retrieve detailed information about a specific bank\
        \ account connection.\n\n        Returns comprehensive information including:\n\
        \        - Account details (name, mask, balance, currency)\n        - Connection\
        \ status and sync information\n        - Bank link context (provider, business)\n\
        \        - Account mapping information\n        - Timestamps and metadata\n\
        \n        **Access Control:**\n        - Only accessible for bank accounts\
        \ belonging to the authenticated partner's businesses\n        "
      summary: Retrieve Bank Account Connection
      parameters:
      - in: path
        name: bank_account_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bank Accounts Management
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccountConnection'
              examples:
                UKBusinessBankAccount(Barclays):
                  value:
                    id: 9f90c3cc-6i00-0h16-eeee-eii81402618g
                    account_key: plaid_acc_Barclays_Checking_1234
                    display_name: Barclays Business Current Account
                    official_name: Barclays Bank PLC - Business Account
                    mask: '1234'
                    balance: 12500.5
                    balance_cents: 1250050
                    currency: GBP
                    is_active: true
                    bank_link_status: active
                    bank_link_id: 8e80c3cc-5h99-9g05-dddd-dhh70291507f
                    business_id: 7d70c3cc-4g88-8f04-cccc-cgg69180406e
                    business_name: The Red Lion Pub Ltd
                    provider: plaid
                    mapped_account: acc-1000-cash
                    created_at: '2024-01-15T10:30:00Z'
                    updated_at: '2024-03-28T14:22:00Z'
                  summary: UK Business Bank Account (Barclays)
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-links/{bank_link_id}/disconnect/:
    delete:
      operationId: disconnect_bank_link
      description: "\n        Disconnect a bank connection by marking it as revoked.\n\
        \n        This operation:\n        - Marks the bank link status as 'revoked'\n\
        \        - Deactivates all associated bank account connections\n        -\
        \ Stops transaction syncing for all accounts under this link\n        - Does\
        \ NOT delete data - historical transactions remain accessible\n\n        **Use\
        \ Cases:**\n        - User wants to disconnect their bank account\n      \
        \  - Switching to new Plaid credentials (disconnect old, reconnect new)\n\
        \        - Troubleshooting authentication issues\n\n        **After Disconnection:**\n\
        \        - Users can reconnect the same bank using the normal connection flow\n\
        \        - The system will create a new bank link with fresh credentials\n\
        \        - Historical data from the old connection remains in the system\n\
        \n        **Access Control:**\n        - Only accessible for bank links belonging\
        \ to the authenticated partner's businesses\n        "
      summary: Disconnect Bank Link
      parameters:
      - in: path
        name: bank_link_id
        schema:
          type: string
        description: Bank Link UUID to disconnect
        required: true
      - in: path
        name: business_id
        schema:
          type: string
        description: Business UUID
        required: true
      tags:
      - Bank Accounts Management
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankLinkDisconnectResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/:
    get:
      operationId: list_bank_transactions
      description: "\n        Retrieve a paginated list of bank transactions for a\
        \ specific business with advanced filtering options.\n\n        Authentication:\n\
        \        - Requires business-scoped Bearer token (ScopedBusinessTokenAuthentication)\n\
        \        - Token business_id must match the business_id in the path\n\n  \
        \      **Default Behavior:**\n        - Returns bank transactions for the\
        \ business in the URL path\n        - Uses summary serializer for list view\
        \ (lighter payload)\n\n        **Filtering Options:**\n\n        **Account\
        \ Filters:**\n        - `account_id`: Filter by mapped account ID\n      \
        \  - `bank_account_connection_id`: Filter by bank account connection\n\n \
        \       **Date Filters:**\n        - `date_from`: Transactions from this date\
        \ (ISO 8601 format)\n        - `date_to`: Transactions to this date (ISO 8601\
        \ format)\n\n        **Transaction Filters:**\n        - `direction`: Filter\
        \ by direction (credit/debit)\n        - `categorization_status`: Filter by\
        \ categorization status (supports multiple values)\n        - `transaction_type`:\
        \ Filter by transaction type (one of: fps, bacs, chaps, direct_debit, standing_order,\
        \ sepa_credit, sepa_debit, sepa_instant, card_payment, atm_withdrawal, bank_transfer,\
        \ fee, interest, other)\n        - `source`: Filter by transaction source\n\
        \        - `currency`: Filter by currency (GBP, EUR, USD)\n\n        **Amount\
        \ Filters:**\n        - `amount_min`: Minimum transaction amount in cents\n\
        \        - `amount_max`: Maximum transaction amount in cents\n\n        **Status\
        \ Filters:**\n        - `is_reconciled`: Filter by reconciliation status\n\
        \        - `needs_categorization`: Filter transactions needing categorization\n\
        \        - `is_categorized`: Filter categorized transactions\n        - `has_parent`:\
        \ Filter split transactions\n        - `has_children`: Filter transactions\
        \ with splits\n\n        **Search:**\n        - `search`: Search across description,\
        \ counterparty, merchant, and reference\n\n        **Ordering:**\n       \
        \ - `ordering`: Order by any field (prefix with '-' for descending)\n    \
        \    - Default: `-date, -created_at` (newest first)\n\n        **Examples:**\n\
        \        - Get credit transactions: `?direction=credit`\n        - Get pending\
        \ categorization: `?categorization_status=pending`\n        - Get multiple\
        \ statuses: `?categorization_status=pending&categorization_status=manual_review`\n\
        \        - Get transactions for date range: `?date_from=2025-01-01&date_to=2025-01-31`\n\
        \        - Search transactions: `?search=amazon`\n        - Filter by amount:\
        \ `?amount_min=10000&amount_max=100000` (amounts in cents)\n        "
      summary: List Bank Transactions (Business-scoped)
      parameters:
      - in: query
        name: account_id
        schema:
          type: string
        description: Filter by mapped account ID (UUID format)
      - in: query
        name: amount_max
        schema:
          type: integer
        description: Filter by maximum amount in cents
      - in: query
        name: amount_min
        schema:
          type: integer
        description: Filter by minimum amount in cents
      - in: query
        name: approval_status
        schema:
          type: array
          items:
            type: string
            x-spec-enum-id: 7b698985e3218bf3
            enum:
            - ai_approved
            - approved
            - pending_approval
        description: |-
          Filter by approval status (supports multiple values: ?approval_status=pending_approval&approval_status=ai_approved)

          * `pending_approval` - Pending Approval
          * `ai_approved` - AI Approved
          * `approved` - Approved
        explode: true
        style: form
      - in: query
        name: bank_account_connection_id
        schema:
          type: string
        description: Filter by bank account connection ID (UUID format)
      - in: query
        name: business_id
        schema:
          type: string
          format: uuid
        description: Filter by business ID
      - in: path
        name: business_id
        schema:
          type: string
        description: Business ID (UUID format) in path
        required: true
      - in: query
        name: categorization_status
        schema:
          type: string
          enum:
          - approved
          - categorized
          - manual_review
          - pending
        description: Filter by categorization status (supports multiple values)
        explode: true
        style: form
      - in: query
        name: category_code
        schema:
          type: string
        description: Filter by category code
      - in: query
        name: category_id
        schema:
          type: string
          format: uuid
        description: Filter by category ID
      - in: query
        name: currency
        schema:
          type: string
          enum:
          - EUR
          - GBP
          - USD
        description: Filter by currency
      - in: query
        name: date_from
        schema:
          type: string
        description: Filter transactions from this date (ISO 8601 format)
      - in: query
        name: date_to
        schema:
          type: string
        description: Filter transactions to this date (ISO 8601 format)
      - in: query
        name: direction
        schema:
          type: string
          enum:
          - credit
          - debit
        description: Filter by transaction direction
      - in: query
        name: has_children
        schema:
          type: boolean
        description: Filter transactions that have child splits
      - in: query
        name: has_parent
        schema:
          type: boolean
        description: Filter transactions that are split from parent
      - in: query
        name: is_categorized
        schema:
          type: boolean
        description: Filter transactions that are categorized
      - in: query
        name: is_reconciled
        schema:
          type: boolean
        description: Filter by reconciliation status
      - in: query
        name: needs_categorization
        schema:
          type: boolean
        description: Filter transactions that need categorization
      - in: query
        name: ordering
        schema:
          type: string
        description: Order by field (prefix with - for descending)
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - in: query
        name: search
        schema:
          type: string
        description: Search in description, counterparty, merchant, and reference
      - in: query
        name: source
        schema:
          type: string
          enum:
          - api
          - csv_import
          - manual
          - open_banking
          - plaid
        description: Filter by transaction source
      - in: query
        name: subcategory_code
        schema:
          type: string
        description: Filter by subcategory code
      - in: query
        name: subcategory_id
        schema:
          type: string
          format: uuid
        description: Filter by subcategory ID
      - in: query
        name: transaction_type
        schema:
          type: string
          enum:
          - atm_withdrawal
          - bacs
          - bank_transfer
          - card_payment
          - chaps
          - direct_debit
          - fee
          - fps
          - interest
          - other
          - sepa_credit
          - sepa_debit
          - sepa_instant
          - standing_order
        description: Filter by transaction type
      tags:
      - Bank Transactions Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedBankTransactionList'
              examples:
                UKBankTransaction(Credit-CustomerPayment):
                  value:
                    count: 123
                    page_info:
                      total_count: 123
                      current_page: 1
                      total_pages: 7
                      page_size: 20
                    results:
                    - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      date: '2024-03-28'
                      amount: 450000
                      display_amount: £4,500.00
                      signed_amount: 450000
                      direction: credit
                      currency: GBP
                      counterparty_name: The Red Lion Pub Ltd
                      merchant_name: The Red Lion Pub Ltd
                      description: Payment for Invoice INV-0042
                      categorization_status: categorized
                      transaction_type: fps
                      subcategory:
                        id: cat-001
                        code: INCOME_SALES
                        name: Sales Revenue
                        category:
                          id: parent-001
                          code: INCOME
                          name: Income
                      business_id: 7d70c3cc-4g88-8f04-cccc-cgg69180406e
                      business_name: Premium Breweries Ltd
                      account_id: acc-1000
                      account_code: '1000'
                      account_name: Bank - Barclays Current
                      bank_account_connection_id: 9f90c3cc-6i00-0h16-eeee-eii81402618g
                      bank_account_name: Barclays Business Current Account
                      bank_account_mask: '1234'
                      bank_account_currency: GBP
                      is_reconciled: true
                      reconciled_at: '2024-03-28T10:15:00Z'
                      reconciled_amount_cents: 450000
                      remaining_amount_cents: 0
                      reconciliations: null
                      created_at: '2024-03-28T10:05:00Z'
                  summary: UK Bank Transaction (Credit - Customer Payment)
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/match-bill-payment/:
    post:
      operationId: reconcile_bill_payment
      description: Create a bill payment record and link it to a bank transaction
        for reconciliation. This operation creates a new BillPayment, BillPaymentAllocation,
        and ReconciliationLink. The bill payment is matched to the bank debit transaction.
      summary: Reconcile bill payment to bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillReconciliationRequestRequest'
            examples:
              ReconcileBillPaymentToBankTransaction:
                value:
                  bill_id: 53ff016e-822f-4aca-8ef3-339363782663
                  payment_method: bank_transfer
                  amount_cents: 50000
                  notes: Payment made via bank transfer
                  evidence:
                    reference: BANK-REF-456
                  created_by: api
                summary: Reconcile bill payment to bank transaction
                description: Create a bill payment and reconcile it with a bank transaction
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/BillReconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BillReconciliationRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/match-customer-credit-note/:
    post:
      operationId: match_customer_credit_note
      description: Create a reconciliation link between a customer credit note and
        a bank transaction. This represents a cash refund to the customer where the
        credit note is paid out via bank transfer. The bank transaction must be a
        DEBIT (money out). Validates currency match and direction.
      summary: Match customer credit note to bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Customer Credit Note Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MatchCustomerCreditNoteRequestRequest'
            examples:
              MatchCustomerCreditNote:
                value:
                  customer_credit_note_id: 567890de-f012-7890-1234-567890123456
                  amount_cents: 15000
                  notes: Cash refund to customer for returned goods
                summary: Match customer credit note
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/MatchCustomerCreditNoteRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/MatchCustomerCreditNoteRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchCustomerCreditNoteResponse'
              examples:
                MatchResponse:
                  value:
                    reconciliation_link_id: abcd1234-5678-90ab-cdef-123456789abc
                    customer_credit_note:
                      id: 567890de-f012-7890-1234-567890123456
                      status: sent
                      total_amount_cents: 15000
                      reconcilable_amount_cents: 0
                      reconciled_amount_cents: 15000
                    bank_transaction:
                      id: bt-12345678-1234-1234-1234-123456789abc
                      amount_cents: 15000
                      direction: debit
                      reconciled_amount_cents: 15000
                    matched_amount_cents: 15000
                  summary: Match response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/match-payment/:
    post:
      operationId: reconcile_invoice_payment
      description: Create a payment record and link it to a bank transaction for reconciliation.
        This operation creates a new Payment, PaymentAllocation, and ReconciliationLink.
        The invoice payment is matched to the bank credit transaction.
      summary: Reconcile invoice payment to bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceReconciliationRequestRequest'
            examples:
              ReconcileInvoicePaymentToBankTransaction:
                value:
                  invoice_id: 53ff016e-822f-4aca-8ef3-339363782663
                  payment_method: bank_transfer
                  amount_cents: 50000
                  notes: Payment received via bank transfer
                  evidence:
                    reference: BANK-REF-123
                  created_by: api
                summary: Reconcile invoice payment to bank transaction
                description: Create a payment and reconcile it with a bank transaction
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/InvoiceReconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InvoiceReconciliationRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/match-payout/:
    post:
      operationId: match_payout
      description: Create a reconciliation link between a payout and a bank transaction.
        This marks the payout as reconciled and updates the bank transaction's unreconciled
        amount. Validates currency match and direction (must be CREDIT for deposits).
      summary: Match payout to bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Payout Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MatchPayoutRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/MatchPayoutRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/MatchPayoutRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchPayoutResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/match-refund-payment/:
    post:
      operationId: reconcile_refund_payment
      description: Create a refund payment record and link it to a bank transaction
        for reconciliation. This operation creates a new RefundPayment and ReconciliationLink.
        The refund payment is matched to the bank debit transaction.
      summary: Reconcile refund payment to bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefundReconciliationRequestRequest'
            examples:
              ReconcileRefundPaymentToBankTransaction:
                value:
                  refund_id: 53ff016e-822f-4aca-8ef3-339363782663
                  payment_method: bank_transfer
                  amount_cents: 50000
                  notes: Refund processed via bank transfer
                  evidence:
                    reference: BANK-REF-789
                  created_by: api
                summary: Reconcile refund payment to bank transaction
                description: Create a refund payment and reconcile it with a bank
                  transaction
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/RefundReconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/RefundReconciliationRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/match-vendor-credit-note/:
    post:
      operationId: match_vendor_credit_note
      description: Create a reconciliation link between a vendor credit note and a
        bank transaction. This represents a cash refund from the vendor where money
        is deposited into the bank. The bank transaction must be a CREDIT (money in).
        Validates currency match and direction.
      summary: Match vendor credit note to bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Vendor Credit Note Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MatchVendorCreditNoteRequestRequest'
            examples:
              MatchVendorCreditNote:
                value:
                  vendor_credit_note_id: 567890de-f012-7890-1234-567890123456
                  amount_cents: 25000
                  notes: Cash refund received from vendor
                summary: Match vendor credit note
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/MatchVendorCreditNoteRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/MatchVendorCreditNoteRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchVendorCreditNoteResponse'
              examples:
                MatchResponse:
                  value:
                    reconciliation_link_id: efgh5678-90ab-cdef-1234-567890abcdef
                    vendor_credit_note:
                      id: 567890de-f012-7890-1234-567890123456
                      status: received
                      total_amount_cents: 25000
                      reconcilable_amount_cents: 0
                      reconciled_amount_cents: 25000
                    bank_transaction:
                      id: bt-98765432-1234-1234-1234-123456789abc
                      amount_cents: 25000
                      direction: credit
                      reconciled_amount_cents: 25000
                    matched_amount_cents: 25000
                  summary: Match response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/match-vendor-refund-payment/:
    post:
      operationId: reconcile_vendor_refund_payment
      description: Create a vendor refund payment record and link it to a bank transaction
        for reconciliation. This operation creates a new VendorRefundPayment and ReconciliationLink.
        The vendor refund payment is matched to the bank credit transaction.
      summary: Reconcile vendor refund payment to bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VendorRefundReconciliationRequestRequest'
            examples:
              ReconcileVendorRefundPaymentToBankTransaction:
                value:
                  vendor_refund_id: 53ff016e-822f-4aca-8ef3-339363782663
                  payment_method: bank_transfer
                  amount_cents: 50000
                  notes: Vendor refund received via bank transfer
                  evidence:
                    reference: BANK-REF-101
                  created_by: api
                summary: Reconcile vendor refund payment to bank transaction
                description: Create a vendor refund payment and reconcile it with
                  a bank transaction
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/VendorRefundReconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/VendorRefundReconciliationRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/unmatch-bill-payment/:
    post:
      operationId: unreconcile_bill_payment
      description: Reverse a previous reconciliation between a bill payment and bank
        transaction. This may delete the payment if it was auto-created during reconciliation.
      summary: Remove bill payment reconciliation from bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - UnReconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillUnreconciliationRequestRequest'
            examples:
              UnreconcileBillPaymentFromBankTransaction:
                value:
                  bill_id: 53ff016e-822f-4aca-8ef3-339363782663
                summary: Unreconcile bill payment from bank transaction
                description: Reverse a reconciliation between bill and bank transaction
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/BillUnreconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BillUnreconciliationRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnreconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/unmatch-customer-credit-note/:
    post:
      operationId: unmatch_customer_credit_note
      description: Reverse a reconciliation link between a customer credit note and
        a bank transaction. This restores the credit note's reconcilable amount.
      summary: Unmatch customer credit note from bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Customer Credit Note Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UnmatchCustomerCreditNoteRequestRequest'
            examples:
              UnmatchCustomerCreditNote:
                value:
                  customer_credit_note_id: 567890de-f012-7890-1234-567890123456
                summary: Unmatch customer credit note
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UnmatchCustomerCreditNoteRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UnmatchCustomerCreditNoteRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnmatchCustomerCreditNoteResponse'
              examples:
                UnmatchResponse:
                  value:
                    unmatched: true
                    customer_credit_note_id: 567890de-f012-7890-1234-567890123456
                    bank_transaction_id: bt-12345678-1234-1234-1234-123456789abc
                    reconciliation_link_id: abcd1234-5678-90ab-cdef-123456789abc
                    reversed_amount_cents: 15000
                  summary: Unmatch response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/unmatch-payment/:
    post:
      operationId: unreconcile_invoice_payment
      description: Reverse a previous reconciliation between an invoice payment and
        bank transaction. This may delete the payment if it was auto-created during
        reconciliation.
      summary: Remove invoice payment reconciliation from bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - UnReconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceUnreconciliationRequestRequest'
            examples:
              UnreconcileInvoicePaymentFromBankTransaction:
                value:
                  invoice_id: 53ff016e-822f-4aca-8ef3-339363782663
                summary: Unreconcile invoice payment from bank transaction
                description: Reverse a reconciliation between invoice and bank transaction
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/InvoiceUnreconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InvoiceUnreconciliationRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnreconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/unmatch-payout/:
    post:
      operationId: unmatch_payout
      description: Reverse a reconciliation link between a payout and a bank transaction.
        This marks the payout as unreconciled and restores the bank transaction's
        unreconciled amount. Allows the payout to be modified or deleted again.
      summary: Unmatch payout from bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Payout Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UnmatchPayoutRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UnmatchPayoutRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UnmatchPayoutRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnmatchPayoutResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/unmatch-refund-payment/:
    post:
      operationId: unreconcile_refund_payment
      description: Reverse a previous reconciliation between a refund payment and
        bank transaction. This may delete the payment if it was auto-created during
        reconciliation.
      summary: Remove refund payment reconciliation from bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - UnReconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefundUnreconciliationRequestRequest'
            examples:
              UnreconcileRefundPaymentFromBankTransaction:
                value:
                  refund_id: 53ff016e-822f-4aca-8ef3-339363782663
                summary: Unreconcile refund payment from bank transaction
                description: Reverse a reconciliation between refund and bank transaction
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/RefundUnreconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/RefundUnreconciliationRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnreconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/unmatch-vendor-credit-note/:
    post:
      operationId: unmatch_vendor_credit_note
      description: Reverse a reconciliation link between a vendor credit note and
        a bank transaction. This restores the credit note's reconcilable amount.
      summary: Unmatch vendor credit note from bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Vendor Credit Note Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UnmatchVendorCreditNoteRequestRequest'
            examples:
              UnmatchVendorCreditNote:
                value:
                  vendor_credit_note_id: 567890de-f012-7890-1234-567890123456
                summary: Unmatch vendor credit note
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UnmatchVendorCreditNoteRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UnmatchVendorCreditNoteRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnmatchVendorCreditNoteResponse'
              examples:
                UnmatchResponse:
                  value:
                    unmatched: true
                    vendor_credit_note_id: 567890de-f012-7890-1234-567890123456
                    bank_transaction_id: bt-98765432-1234-1234-1234-123456789abc
                    reconciliation_link_id: efgh5678-90ab-cdef-1234-567890abcdef
                    reversed_amount_cents: 25000
                  summary: Unmatch response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bank-transactions/{bank_transaction_id}/unmatch-vendor-refund-payment/:
    post:
      operationId: unreconcile_vendor_refund_payment
      description: Reverse a previous reconciliation between a vendor refund payment
        and bank transaction. This may delete the payment if it was auto-created during
        reconciliation.
      summary: Remove vendor refund payment reconciliation from bank transaction
      parameters:
      - in: path
        name: bank_transaction_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - UnReconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VendorRefundUnreconciliationRequestRequest'
            examples:
              UnreconcileVendorRefundPaymentFromBankTransaction:
                value:
                  vendor_refund_id: 53ff016e-822f-4aca-8ef3-339363782663
                summary: Unreconcile vendor refund payment from bank transaction
                description: Reverse a reconciliation between vendor refund and bank
                  transaction
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/VendorRefundUnreconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/VendorRefundUnreconciliationRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnreconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bank-transactions/grouped-by-category/:
    get:
      operationId: list_bank_transactions_grouped_by_category
      description: "\n        Retrieve a paginated list of bank transactions for a\
        \ specific business grouped by category or subcategory.\n\n        Authentication:\n\
        \        - Requires business-scoped Bearer token (ScopedBusinessTokenAuthentication)\n\
        \        - Token business_id must match the business_id in the path\n\n  \
        \      **How it works:**\n        - Applies standard pagination to transactions\
        \ (e.g., 100 transactions per page)\n        - Groups the paginated transactions\
        \ by category (default) or subcategory (if group_by=subcategory)\n       \
        \ - Returns hierarchical structure with category/subcategory metadata\n\n\
        \        **Grouping Options:**\n        - `group_by=category` (default): Groups\
        \ by top-level category (e.g., \"Travel & Transport\")\n        - `group_by=subcategory`:\
        \ Groups by subcategory (e.g., \"Travel & Transport: Local transport\")\n\n\
        \n        **Filtering Options:**\n        Uses the same filtering options\
        \ as the standard bank transactions endpoint:\n\n        **Business & Account\
        \ Filters:**\n        - `business_id`: Filter by specific business UUID\n\
        \        - `account_id`: Filter by mapped account ID\n        - `bank_account_connection_id`:\
        \ Filter by bank account connection\n\n        **Date Filters:**\n       \
        \ - `date_from`: Transactions from this date (ISO 8601 format)\n        -\
        \ `date_to`: Transactions to this date (ISO 8601 format)\n\n        **Transaction\
        \ Filters:**\n        - `direction`: Filter by direction (credit/debit)\n\
        \        - `categorization_status`: Filter by categorization status (supports\
        \ multiple values)\n        - `transaction_type`: Filter by transaction type\n\
        \        - `source`: Filter by transaction source\n        - `currency`: Filter\
        \ by currency (GBP, EUR, USD)\n\n        **Amount Filters:**\n        - `amount_min`:\
        \ Minimum transaction amount in cents\n        - `amount_max`: Maximum transaction\
        \ amount in cents\n\n        **Status Filters:**\n        - `is_reconciled`:\
        \ Filter by reconciliation status\n        - `needs_categorization`: Filter\
        \ transactions needing categorization\n        - `is_categorized`: Filter\
        \ categorized transactions\n\n        **Search:**\n        - `search`: Search\
        \ across description, counterparty, merchant, and reference\n\n        **Ordering:**\n\
        \        - `ordering`: Order by any field (prefix with '-' for descending)\n\
        \        - Default: `-date, -created_at` (newest first)\n        - New: `subcategory__category__name`,\
        \ `subcategory__name` ordering available\n\n        **Examples:**\n      \
        \  - Get grouped credit transactions: `?direction=credit`\n        - Get grouped\
        \ pending categorization: `?categorization_status=pending`\n        - Get\
        \ grouped multiple statuses: `?categorization_status=pending&categorization_status=manual_review`\n\
        \        - Get grouped transactions for date range: `?date_from=2025-01-01&date_to=2025-01-31`\n\
        \        - Order by category: `?ordering=subcategory__category__name`\n  \
        \      "
      summary: List Bank Transactions Grouped by Category or Subcategory (Business-scoped)
      parameters:
      - in: query
        name: account_id
        schema:
          type: string
        description: Filter by mapped account ID (UUID format)
      - in: query
        name: amount_max
        schema:
          type: number
          format: double
        description: Filter by maximum amount
      - in: query
        name: amount_min
        schema:
          type: number
          format: double
        description: Filter by minimum amount
      - in: query
        name: approval_status
        schema:
          type: array
          items:
            type: string
            x-spec-enum-id: 7b698985e3218bf3
            enum:
            - ai_approved
            - approved
            - pending_approval
        description: |-
          Filter by approval status (supports multiple values: ?approval_status=pending_approval&approval_status=ai_approved)

          * `pending_approval` - Pending Approval
          * `ai_approved` - AI Approved
          * `approved` - Approved
        explode: true
        style: form
      - in: query
        name: bank_account_connection_id
        schema:
          type: string
        description: Filter by bank account connection ID (UUID format)
      - in: query
        name: business_id
        schema:
          type: string
          format: uuid
        description: Filter by business ID
      - in: path
        name: business_id
        schema:
          type: string
        description: Business ID (UUID format) in path
        required: true
      - in: query
        name: categorization_status
        schema:
          type: string
          enum:
          - approved
          - categorized
          - manual_review
          - pending
        description: Filter by categorization status (supports multiple values)
        explode: true
        style: form
      - in: query
        name: category_code
        schema:
          type: string
        description: Filter by category code
      - in: query
        name: category_id
        schema:
          type: string
          format: uuid
        description: Filter by category ID
      - in: query
        name: currency
        schema:
          type: string
          enum:
          - EUR
          - GBP
          - USD
        description: Filter by currency
      - in: query
        name: date_from
        schema:
          type: string
        description: Filter transactions from this date (ISO 8601 format)
      - in: query
        name: date_to
        schema:
          type: string
        description: Filter transactions to this date (ISO 8601 format)
      - in: query
        name: direction
        schema:
          type: string
          enum:
          - credit
          - debit
        description: Filter by transaction direction
      - in: query
        name: group_by
        schema:
          type: string
          enum:
          - category
          - subcategory
        description: Group transactions by category (default) or subcategory
      - in: query
        name: has_children
        schema:
          type: boolean
        description: Filter transactions that have child splits
      - in: query
        name: has_parent
        schema:
          type: boolean
        description: Filter transactions that are split from parent
      - in: query
        name: is_categorized
        schema:
          type: boolean
        description: Filter transactions that are categorized
      - in: query
        name: is_reconciled
        schema:
          type: boolean
        description: Filter by reconciliation status
      - in: query
        name: needs_categorization
        schema:
          type: boolean
        description: Filter transactions that need categorization
      - in: query
        name: ordering
        schema:
          type: string
        description: 'Order by field (prefix with - for descending). New: subcategory__category__name,
          subcategory__name available'
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - in: query
        name: search
        schema:
          type: string
        description: Search in description, counterparty, merchant, and reference
      - in: query
        name: source
        schema:
          type: string
          enum:
          - api
          - csv_import
          - manual
          - open_banking
          - plaid
        description: Filter by transaction source
      - in: query
        name: subcategory_code
        schema:
          type: string
        description: Filter by subcategory code
      - in: query
        name: subcategory_id
        schema:
          type: string
          format: uuid
        description: Filter by subcategory ID
      - in: query
        name: transaction_type
        schema:
          type: string
          enum:
          - atm_withdrawal
          - bacs
          - bank_transfer
          - card_payment
          - chaps
          - direct_debit
          - fee
          - fps
          - interest
          - other
          - sepa_credit
          - sepa_debit
          - sepa_instant
          - standing_order
        description: Filter by transaction type
      tags:
      - Bank Transactions Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedBankTransactionCategoryGroupingResponseList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/bills/:
    get:
      operationId: list_bills
      description: List all bills for a business with filters for status, vendor,
        dates, reference numbers, and amounts. Supports standardized pagination.
      summary: List bills
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: due_at_end
        schema:
          type: string
          format: date-time
        description: Bills due on/before this timestamp (ISO format)
      - in: query
        name: due_at_start
        schema:
          type: string
          format: date-time
        description: Bills due on/after this timestamp (ISO format)
      - in: query
        name: max_amount
        schema:
          type: integer
        description: Maximum total amount in cents
      - in: query
        name: memo
        schema:
          type: string
        description: Exact memo match
      - in: query
        name: memo_contains
        schema:
          type: string
        description: Memo contains substring (case-insensitive)
      - in: query
        name: min_amount
        schema:
          type: integer
        description: Minimum total amount in cents
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (1-indexed, default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Number of items per page (default: 20, max: 100)'
      - in: query
        name: received_at_end
        schema:
          type: string
          format: date-time
        description: Bills received on/before this timestamp (ISO format)
      - in: query
        name: received_at_start
        schema:
          type: string
          format: date-time
        description: Bills received on/after this timestamp (ISO format)
      - in: query
        name: reference_numbers
        schema:
          type: string
        description: Filter by reference numbers (comma-separated). Searches bill_number,
          vendor_bill_number, purchase_order_number
      - in: query
        name: search
        schema:
          type: string
      - in: query
        name: sort
        schema:
          type: string
          default: -created_at
        description: 'Sort order. Values: created_at, -created_at, updated_at, -updated_at
          (prefix with - for descending)'
      - in: query
        name: status
        schema:
          type: string
        description: 'Filter by bill status (comma-separated). Values: received, partially_paid,
          paid, voided'
      - in: query
        name: vendor_external_id
        schema:
          type: string
        description: Filter by vendor external ID
      - in: query
        name: vendor_id
        schema:
          type: string
        description: Filter by vendor ID (supports comma-separated UUIDs for multiple
          vendors)
      tags:
      - Bills
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedBillList'
          description: ''
      x-audience:
      - partner
    post:
      operationId: create_bill
      description: Create a new bill for a business with line items. Supports idempotency
        via external_id.
      summary: Create bill
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Bills
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillCreateAPIRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/BillCreateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BillCreateAPIRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bill'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bills/{bill_id}/:
    get:
      operationId: get_bill
      description: Retrieve a single bill by ID for the specified business.
      summary: Get bill
      parameters:
      - in: path
        name: bill_id
        schema:
          type: string
          format: uuid
        description: Bill ID
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business ID
        required: true
      tags:
      - Bills
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bill'
          description: ''
      x-audience:
      - partner
    put:
      operationId: update_bill
      description: |-
        Update bill via PUT.

        **Line Items**: If `line_items` is provided, ALL existing line items are deleted and replaced. If omitted, line items remain unchanged.
      summary: Update bill
      parameters:
      - in: path
        name: bill_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this bill.
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Bills
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillUpdateAPIRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/BillUpdateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BillUpdateAPIRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bill'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bills/{bill_id}/void/:
    post:
      operationId: void_bill
      description: Marks a bill as voided. If the bill has payments applied, this
        will still mark as voided but does not alter allocations in this simplified
        implementation.
      summary: Void bill
      parameters:
      - in: path
        name: bill_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this bill.
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Bills
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/BillRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BillRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bill'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bills/payments/:
    get:
      operationId: list_bill_payments
      description: "\n        List all bill payments for a business with filtering\
        \ and pagination.\n\n        **Features:**\n        - Filter by status (pending,\
        \ processing, completed, failed, cancelled, returned)\n        - Filter by\
        \ payment method\n        - Filter by vendor\n        - Filter by bill\n \
        \       - Filter by date range\n        - Search by payment reference\n  \
        \      - Pagination support (default: 20 per page, max: 100)\n\n        **Use\
        \ Cases:**\n        - View all pending payments requiring processing\n   \
        \     - Monitor payment status across all bills\n        - Generate payment\
        \ reports\n        - Reconciliation dashboard\n\n        **Available Filters:**\n\
        \        - `status`: Filter by payment status\n        - `payment_method`:\
        \ Filter by payment method (bank_transfer, ach, wire, check, etc.)\n     \
        \   - `vendor_id`: Filter by vendor UUID\n        - `bill_id`: Filter by bill\
        \ UUID\n        - `payment_date_start` / `payment_date_end`: Filter by date\
        \ range\n        - `search`: Search by payment_reference, check_number, processor_payment_id\n\
        \        "
      summary: List bill payments
      parameters:
      - in: query
        name: bill_id
        schema:
          type: string
          format: uuid
        description: Filter by bill UUID
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - in: query
        name: payment_date_end
        schema:
          type: string
          format: date
        description: Filter payments to this date (YYYY-MM-DD)
      - in: query
        name: payment_date_start
        schema:
          type: string
          format: date
        description: Filter payments from this date (YYYY-MM-DD)
      - in: query
        name: payment_method
        schema:
          type: string
        description: Filter by payment method
      - in: query
        name: search
        schema:
          type: string
        description: Search by payment reference, check number, or processor payment
          ID
      - in: query
        name: status
        schema:
          type: string
        description: Filter by payment status
      - in: query
        name: vendor_id
        schema:
          type: string
        description: Filter by vendor ID (supports comma-separated UUIDs for multiple
          vendors)
      tags:
      - Bill Payments
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedBillPaymentListList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: create_bill_payment_allocation
      description: "\n        Create a bill payment with embedded allocations in a\
        \ single atomic operation.\n\n        This endpoint follows the same pattern\
        \ as invoice payments and vendor refund payments,\n        where allocations\
        \ are embedded in the payment creation request.\n\n        **Key Features:**\n\
        \        - Atomic operation - all or nothing\n        - Comprehensive validation\n\
        \        - Support for multiple bill allocations\n        - Idempotency support\
        \ via `Idempotency-Key` header\n\n        **Idempotency:**\n        Include\
        \ an `Idempotency-Key` header to ensure the same request isn't processed twice.\n\
        \        If the same key is used again, the original response will be returned.\n\
        \n        **Example Request:**\n        ```json\n        {\n          \"vendor_id\"\
        : \"uuid\",\n          \"amount_cents\": 100000,\n          \"payment_method\"\
        : \"bank_transfer\",\n          \"payment_date\": \"2025-01-15\",\n      \
        \    \"allocations\": [\n            {\n              \"bill_id\": \"uuid\"\
        ,\n              \"amount_cents\": 60000,\n              \"description\":\
        \ \"Partial payment for Bill #123\"\n            },\n            {\n     \
        \         \"bill_id\": \"uuid\",\n              \"amount_cents\": 40000,\n\
        \              \"description\": \"Full payment for Bill #124\"\n         \
        \   }\n          ]\n        }\n        ```\n        "
      summary: Create bill payment with allocations
      parameters:
      - in: header
        name: Idempotency-Key
        schema:
          type: string
        description: Unique key for idempotent request processing
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - Bill Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillPaymentCreateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/BillPaymentCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BillPaymentCreateRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillPaymentResponse'
          description: ''
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillPaymentResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bills/payments/{bill_payment_id}/:
    get:
      operationId: get_bill_payment
      description: "\n        Retrieve detailed information about a specific bill\
        \ payment.\n\n        **Returns:**\n        - Complete payment information\n\
        \        - Associated vendor details\n        - Allocations (bills paid)\n\
        \        - Reconciliation status\n\n        **Use Cases:**\n        - View\
        \ payment status and details\n        - Check allocation breakdown\n     \
        \   - Audit trail\n        - Debugging and support\n        "
      summary: Get bill payment details
      parameters:
      - in: path
        name: bill_payment_id
        schema:
          type: string
          format: uuid
        description: Bill Payment UUID
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - Bill Payments
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillPaymentResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    patch:
      operationId: update_bill_payment
      description: "\n        Update an existing bill payment's status or details.\n\
        \n        **Updatable Fields:**\n        - `status`: Update payment status\
        \ (with validation)\n        - `failure_reason`: Required when status is 'failed'\n\
        \        - `payment_reference`: Update external reference\n        - `processing_fee_cents`:\
        \ Update processing fee\n\n        **Status Transitions:**\n        - `pending`\
        \ → `processing`, `completed`, `failed`, `cancelled`\n        - `processing`\
        \ → `completed`, `failed`\n        - `completed` → (no transitions allowed)\n\
        \        - `failed` → (no transitions allowed)\n        - `cancelled` → (no\
        \ transitions allowed)\n        "
      summary: Update bill payment
      parameters:
      - in: path
        name: bill_payment_id
        schema:
          type: string
          format: uuid
        description: Bill Payment UUID
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - Bill Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedBillPaymentUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedBillPaymentUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedBillPaymentUpdateRequest'
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillPaymentResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/bills/payments/{bill_payment_id}/delete/:
    post:
      operationId: delete_bill_payment
      description: Cancel a bill payment and reverse its allocations. Only pending
        or failed payments can be deleted. Completed payments cannot be deleted. This
        operation marks the payment as cancelled and updates bill statuses. Following
        the REST pattern, this uses POST method as it's a state change operation,
        not a resource deletion.
      summary: Delete (cancel) bill payment
      parameters:
      - in: path
        name: bill_payment_id
        schema:
          type: string
          format: uuid
        description: Bill Payment UUID
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - Bill Payments
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillPaymentCancelResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/create-link-token/:
    post:
      operationId: create_link_token
      description: Create Plaid link token for frontend initialization
      summary: Create Link Token
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Plaid Integration APIs
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LinkTokenRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/LinkTokenRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/LinkTokenRequest'
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinkTokenResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/customer-credits/:
    get:
      operationId: list_customer_credits
      description: List all customer credits for a business with filtering and pagination.
      summary: List Customer Credits
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: query
        name: customer_external_id
        schema:
          type: string
        description: Filter by customer external id
      - in: query
        name: customer_id
        schema:
          type: string
        description: Filter by customer ID (supports comma-separated UUIDs for multiple
          customers)
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: search
        schema:
          type: string
        description: Search in credit note number, external ID, and customer name
      - in: query
        name: sent_at_end
        schema:
          type: string
        description: Filter credits sent at or before this ISO timestamp
      - in: query
        name: sent_at_start
        schema:
          type: string
        description: Filter credits sent at or after this ISO timestamp
      - in: query
        name: source_invoice_id
        schema:
          type: string
          format: uuid
        description: Filter by source invoice ID (origin tracking)
      - in: query
        name: status
        schema:
          type: string
        description: Comma-separated statuses (draft,sent,applied,partially_applied,void)
      tags:
      - Customer Credits
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedCustomerCreditList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    post:
      operationId: create_customer_credit
      description: Create a customer credit note with line items and optional allocations.
      summary: Create Customer Credit
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      tags:
      - Customer Credits
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCustomerCreditRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateCustomerCreditRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateCustomerCreditRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerCredit'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/customer-credits/{credit_id}/:
    get:
      operationId: get_customer_credit
      description: Retrieve a single customer credit by ID with all line items and
        allocations.
      summary: Get Customer Credit
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: credit_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this customer credit note.
        required: true
      tags:
      - Customer Credits
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerCredit'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    put:
      operationId: update_customer_credit
      description: Update customer credit.
      summary: Update Customer Credit
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: credit_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this customer credit note.
        required: true
      tags:
      - Customer Credits
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCustomerCreditRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UpdateCustomerCreditRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UpdateCustomerCreditRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerCredit'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    delete:
      operationId: delete_customer_credit
      description: Soft delete customer credit.
      summary: Delete (soft) Customer Credit
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: credit_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this customer credit note.
        required: true
      tags:
      - Customer Credits
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/customer-credits/{credit_id}/void/:
    post:
      operationId: v1_platform_businesses_customer_credits_void_create
      description: Void a customer credit note.
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: credit_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this customer credit note.
        required: true
      tags:
      - v1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerCreditRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CustomerCreditRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CustomerCreditRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerCredit'
          description: ''
  /v1/platform/businesses/{business_id}/customers/:
    get:
      operationId: list_customers
      description: List all customers within a business. Only active customers are
        returned by default, but archived customers can be included via the include_archived
        flag. Supports standardized pagination.
      summary: List customers
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: query
        name: external_id
        schema:
          type: string
        description: The external ID of the customer to fetch (exact match).
      - in: query
        name: external_id_contains
        schema:
          type: string
        description: A case-insensitive substring used to filter customers whose external
          ID contains the specified value.
      - in: query
        name: include_archived
        schema:
          type: boolean
          default: false
        description: Include archived customers in the response. Defaults to false.
      - in: query
        name: name
        schema:
          type: string
        description: The exact name of the customers to fetch (company or individual
          name).
      - in: query
        name: name_contains
        schema:
          type: string
        description: A case-insensitive substring used to filter customers whose name
          contains the specified value.
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (1-indexed, default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Number of items per page (default: 20, max: 100)'
      tags:
      - Customers
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedCustomerList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: create_customer
      description: Create a new customer within a business. Returns the created customer
        in the same format as the get customer endpoint.
      summary: Create a customer
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      tags:
      - Customers
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCustomerRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateCustomerRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateCustomerRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/customers/{customer_id}/:
    get:
      operationId: get_customer
      description: Get an existing customer.
      summary: Get a customer
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: customer_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this customer.
        required: true
      tags:
      - Customers
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    put:
      operationId: update_customer
      description: Update an existing customer. Returns the updated customer in the
        same format as the get customer endpoint.
      summary: Update a customer
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: customer_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this customer.
        required: true
      tags:
      - Customers
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCustomerRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UpdateCustomerRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UpdateCustomerRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/customers/{customer_id}/archive/:
    post:
      operationId: archive_customer
      description: Archive a customer, hiding them from the business's active customer
        list. Archived customers can still be accessed by ID but are not returned
        in list requests by default.
      summary: Archive a customer
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: customer_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this customer.
        required: true
      tags:
      - Customers
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CustomerRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CustomerRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/customers/{customer_id}/unarchive/:
    post:
      operationId: unarchive_customer
      description: Reactivate an archived customer, making them available in the business's
        active customer list. Only archived customers can be unarchived.
      summary: Unarchive a customer
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: customer_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this customer.
        required: true
      tags:
      - Customers
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CustomerRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CustomerRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/documents/upload:
    post:
      operationId: unified_document_upload
      description: "\n        Upload a financial document file for automated AI-powered\
        \ AR/AP classification and processing.\n\n        **Processing Flow:**\n \
        \       1. Document is uploaded to S3 storage\n        2. Background unified\
        \ workflow is queued\n        3. API returns immediately (202 Accepted)\n\
        \        4. Background workflow processing:\n           - Extracts document\
        \ data using Reducto AI\n           - Classifies as AR (Accounts Receivable)\
        \ or AP (Accounts Payable)\n           - Routes to appropriate workflow:\n\
        \             - AR: Sales invoices, customer credit notes (you are the issuer)\n\
        \             - AP: Bills, receipts, vendor credit notes (you are the recipient)\n\
        \           - Matches or creates customer/vendor using AI\n           - Creates\
        \ appropriate entity record\n        5. Extracted entity appears in respective\
        \ API endpoint\n\n        **File Requirements:**\n        - Format: PDF or\
        \ images (PNG, JPEG, GIF, BMP, TIFF, HEIC)\n        - Size: Maximum 50MB for\
        \ PDF, 10-20MB for images\n        - Content: Financial document (invoice,\
        \ bill, receipt, credit note)\n        - Content-Type validation: File content\
        \ is verified to match declared type\n\n        **Classification Confidence:**\n\
        \        - High confidence (≥80%): Document processed automatically\n    \
        \    - Low confidence (<80%): Document marked as failed, manual classification\
        \ required\n\n        **Access Control:**\n        - Requires partner authentication\n\
        \        - Business must belong to authenticated partner\n        "
      summary: Upload Document for AI Classification (AR/AP)
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Documents
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UnifiedDocumentUploadRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UnifiedDocumentUploadRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UnifiedDocumentUploadRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnifiedDocumentUploadResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/exchange-token/:
    post:
      operationId: exchange_public_token
      description: Exchange Plaid public token for access token and automatically
        fetch/store bank accounts
      summary: Exchange Public Token
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Plaid Integration APIs
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenExchangeRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TokenExchangeRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/TokenExchangeRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenExchangeResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/fetch-accounts/:
    get:
      operationId: fetch_accounts
      description: Get all bank account connections from Plaid for the specified business
      summary: Get Business Bank Accounts
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Plaid Integration APIs
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountFetchResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/financial-documents/:
    get:
      operationId: list_financial_documents
      description: |-
        List all financial documents for a business. Includes documents created via document upload workflow (AR invoices, AP bills, credit notes, and generic documents).

        **Review Queue**: Use `needs_review=true` to get documents requiring human review.
      summary: List financial documents
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: created_at_end
        schema:
          type: string
          format: date-time
      - in: query
        name: created_at_start
        schema:
          type: string
          format: date-time
      - in: query
        name: customer_external_id
        schema:
          type: string
      - in: query
        name: customer_id
        schema:
          type: string
          format: uuid
        description: Filter by customer ID (AR documents)
      - in: query
        name: document_type
        schema:
          type: string
        description: 'Filter by document type (comma-separated). Values: sales_invoice,
          credit_note, bill, vendor_credit_note, statement, contract, other'
      - in: query
        name: due_date_end
        schema:
          type: string
          format: date
        description: Documents due on/before this date
      - in: query
        name: due_date_start
        schema:
          type: string
          format: date
        description: Documents due on/after this date
      - in: query
        name: external_id
        schema:
          type: string
      - in: query
        name: max_amount
        schema:
          type: integer
        description: Maximum total amount in cents
      - in: query
        name: min_amount
        schema:
          type: integer
        description: Minimum total amount in cents
      - in: query
        name: min_classification_confidence
        schema:
          type: number
          format: float
        description: Minimum classification confidence (0.0-1.0)
      - in: query
        name: min_extraction_confidence
        schema:
          type: number
          format: float
        description: Minimum extraction confidence (0.0-1.0)
      - in: query
        name: needs_review
        schema:
          type: boolean
        description: Filter by review status (true = needs review)
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (1-indexed, default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Number of items per page (default: 20, max: 100)'
      - in: query
        name: reference_date_end
        schema:
          type: string
          format: date
        description: Documents with reference date on/before this date
      - in: query
        name: reference_date_start
        schema:
          type: string
          format: date
        description: Documents with reference date on/after this date
      - in: query
        name: reference_number
        schema:
          type: string
      - in: query
        name: search
        schema:
          type: string
        description: Search reference number, external ID, or counterparty name
      - in: query
        name: sort
        schema:
          type: string
          default: -created_at
        description: 'Sort order. Values: created_at, -created_at, reference_date,
          -reference_date, due_date, -due_date (prefix with - for descending)'
      - in: query
        name: status
        schema:
          type: string
        description: 'Filter by status (comma-separated). Values: draft, pending_review,
          approved, sent, posted, partially_paid, paid, overdue, applied, partially_applied,
          void, cancelled, processed'
      - in: query
        name: vendor_external_id
        schema:
          type: string
      - in: query
        name: vendor_id
        schema:
          type: string
          format: uuid
        description: Filter by vendor ID (AP documents)
      - in: query
        name: workflow_type
        schema:
          type: string
        description: 'Filter by workflow type (comma-separated). Values: ar, ap, generic'
      tags:
      - Financial Documents
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedFinancialDocumentList'
              examples:
                ListResponse:
                  value:
                    count: 123
                    page_info:
                      total_count: 123
                      current_page: 1
                      total_pages: 7
                      page_size: 20
                    results:
                    - count: 3
                      next: null
                      previous: null
                      results:
                      - type: FinancialDocumentData
                        id: 550e8400-e29b-41d4-a716-446655440000
                        business_id: 123e4567-e89b-12d3-a456-426614174000
                        external_id: doc-ext-001
                        workflow_type: AR
                        document_type: SALES_INVOICE
                        status: DRAFT
                        counterparty:
                          id: 789abcde-f234-5678-9012-345678901234
                          type: customer
                          display_name: Acme Corporation Ltd
                          external_id: cust-001
                        reference_number: INV-2024-001
                        reference_date: '2024-01-15'
                        due_date: '2024-02-14'
                        payment_terms: Net 30
                        currency: GBP
                        subtotal: 100000
                        tax_amount: 20000
                        total_amount: 120000
                        amount_paid: 0
                        amount_due: 120000
                        is_overdue: false
                        is_fully_paid: false
                        needs_review: false
                        review_reasons: []
                        reviewed_at: null
                        extraction_confidence: 0.95
                        classification_confidence: 0.92
                        line_items:
                        - id: 660e8400-e29b-41d4-a716-446655440000
                          financial_document_id: 550e8400-e29b-41d4-a716-446655440000
                          line_number: 1
                          description: Professional consulting services
                          sku: null
                          quantity: 10.0
                          unit_price: 10000
                          amount: 100000
                          tax_rate: 20.0
                          tax_amount: 20000
                          account_id: 234567ab-cdef-4567-8901-234567890123
                          account_code: '4000'
                          tracking_categories: {}
                          metadata: {}
                        summary: null
                        source_document_id: 770e8400-e29b-41d4-a716-446655440000
                        document:
                          id: 770e8400-e29b-41d4-a716-446655440000
                          url: https://storage.example.com/presigned-url-abc123
                          file_name: invoice-2024-001.pdf
                          expires_at: '2024-01-15T12:00:00Z'
                        journal_entry_id: null
                        posted_at: null
                        created_at: '2024-01-15T10:00:00Z'
                        updated_at: '2024-01-15T10:00:00Z'
                      - type: FinancialDocumentData
                        id: 661e8400-e29b-41d4-a716-446655440000
                        business_id: 123e4567-e89b-12d3-a456-426614174000
                        external_id: doc-ext-002
                        workflow_type: AP
                        document_type: BILL
                        status: PENDING_REVIEW
                        counterparty:
                          id: 456e7890-e12b-34c5-d678-901234567890
                          type: vendor
                          display_name: Tech Services Ltd
                          external_id: vendor-001
                        reference_number: BILL-2024-001
                        reference_date: '2024-01-10'
                        due_date: '2024-02-09'
                        payment_terms: Net 30
                        currency: GBP
                        subtotal: 80000
                        tax_amount: 16000
                        total_amount: 96000
                        amount_paid: 0
                        amount_due: 96000
                        is_overdue: false
                        is_fully_paid: false
                        needs_review: true
                        review_reasons:
                        - low_extraction_confidence
                        - missing_line_item_accounts
                        reviewed_at: null
                        extraction_confidence: 0.72
                        classification_confidence: 0.88
                        line_items:
                        - id: 771e8400-e29b-41d4-a716-446655440000
                          financial_document_id: 661e8400-e29b-41d4-a716-446655440000
                          line_number: 1
                          description: Cloud hosting services - January 2024
                          sku: CLOUD-HOST-001
                          quantity: 1.0
                          unit_price: 80000
                          amount: 80000
                          tax_rate: 20.0
                          tax_amount: 16000
                          account_id: 234567ab-cdef-4567-8901-234567890123
                          account_code: '6100'
                          tracking_categories:
                            department: Engineering
                          metadata: {}
                        summary: null
                        source_document_id: 881e8400-e29b-41d4-a716-446655440000
                        document:
                          id: 881e8400-e29b-41d4-a716-446655440000
                          url: https://storage.example.com/presigned-url-def456
                          file_name: bill-tech-services-jan2024.pdf
                          expires_at: '2024-01-15T12:00:00Z'
                        journal_entry_id: null
                        posted_at: null
                        created_at: '2024-01-10T09:30:00Z'
                        updated_at: '2024-01-10T09:30:00Z'
                      - type: FinancialDocumentData
                        id: 772e8400-e29b-41d4-a716-446655440000
                        business_id: 123e4567-e89b-12d3-a456-426614174000
                        external_id: doc-ext-003
                        workflow_type: AR
                        document_type: CREDIT_NOTE
                        status: SENT
                        counterparty:
                          id: 789abcde-f234-5678-9012-345678901234
                          type: customer
                          display_name: Acme Corporation Ltd
                          external_id: cust-001
                        reference_number: CN-2024-001
                        reference_date: '2024-01-20'
                        due_date: null
                        payment_terms: null
                        currency: GBP
                        subtotal: 25000
                        tax_amount: 5000
                        total_amount: 30000
                        amount_paid: 0
                        amount_due: 30000
                        is_overdue: false
                        is_fully_paid: false
                        needs_review: false
                        review_reasons: []
                        reviewed_at: '2024-01-20T11:00:00Z'
                        extraction_confidence: 0.98
                        classification_confidence: 0.96
                        line_items:
                        - id: 882e8400-e29b-41d4-a716-446655440000
                          financial_document_id: 772e8400-e29b-41d4-a716-446655440000
                          line_number: 1
                          description: Credit for returned goods
                          sku: null
                          quantity: 1.0
                          unit_price: 25000
                          amount: 25000
                          tax_rate: 20.0
                          tax_amount: 5000
                          account_id: 234567ab-cdef-4567-8901-234567890123
                          account_code: '4000'
                          tracking_categories: {}
                          metadata:
                            return_reason: damaged_goods
                        summary: null
                        source_document_id: 992e8400-e29b-41d4-a716-446655440000
                        document:
                          id: 992e8400-e29b-41d4-a716-446655440000
                          url: https://storage.example.com/presigned-url-ghi789
                          file_name: credit-note-2024-001.pdf
                          expires_at: '2024-01-20T12:00:00Z'
                        journal_entry_id: null
                        posted_at: null
                        created_at: '2024-01-20T10:00:00Z'
                        updated_at: '2024-01-20T11:00:00Z'
                  summary: List Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: v1_platform_businesses_financial_documents_create
      description: |-
        Block document creation via API.

        POST /financial-documents/ is not allowed.
        Documents are created via the document upload workflow, not directly via API.
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - v1
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinancialDocument'
          description: ''
  /v1/platform/businesses/{business_id}/financial-documents/{document_id}/:
    get:
      operationId: get_financial_document
      description: Retrieve a single financial document by ID.
      summary: Get financial document
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business ID
        required: true
      - in: path
        name: document_id
        schema:
          type: string
          format: uuid
        description: Financial document ID
        required: true
      tags:
      - Financial Documents
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinancialDocument'
              examples:
                ARInvoice:
                  value:
                    type: FinancialDocumentData
                    id: 550e8400-e29b-41d4-a716-446655440000
                    business_id: 123e4567-e89b-12d3-a456-426614174000
                    external_id: doc-ext-001
                    workflow_type: AR
                    document_type: SALES_INVOICE
                    status: DRAFT
                    counterparty:
                      id: 789abcde-f234-5678-9012-345678901234
                      type: customer
                      display_name: Acme Corporation Ltd
                      external_id: cust-001
                    reference_number: INV-2024-001
                    reference_date: '2024-01-15'
                    due_date: '2024-02-14'
                    payment_terms: Net 30
                    currency: GBP
                    subtotal: 100000
                    tax_amount: 20000
                    total_amount: 120000
                    amount_paid: 0
                    amount_due: 120000
                    is_overdue: false
                    is_fully_paid: false
                    needs_review: false
                    review_reasons: []
                    reviewed_at: null
                    extraction_confidence: 0.95
                    classification_confidence: 0.92
                    line_items:
                    - id: 660e8400-e29b-41d4-a716-446655440000
                      financial_document_id: 550e8400-e29b-41d4-a716-446655440000
                      line_number: 1
                      description: Professional consulting services
                      sku: null
                      quantity: 10.0
                      unit_price: 10000
                      amount: 100000
                      tax_rate: 20.0
                      tax_amount: 20000
                      account_id: 234567ab-cdef-4567-8901-234567890123
                      account_code: '4000'
                      tracking_categories: {}
                      metadata: {}
                    summary: null
                    source_document_id: 770e8400-e29b-41d4-a716-446655440000
                    document:
                      id: 770e8400-e29b-41d4-a716-446655440000
                      url: https://storage.example.com/presigned-url-abc123
                      file_name: invoice-2024-001.pdf
                      expires_at: '2024-01-15T12:00:00Z'
                    journal_entry_id: null
                    posted_at: null
                    created_at: '2024-01-15T10:00:00Z'
                    updated_at: '2024-01-15T10:00:00Z'
                  summary: AR Invoice
                APBill:
                  value:
                    type: FinancialDocumentData
                    id: 661e8400-e29b-41d4-a716-446655440000
                    business_id: 123e4567-e89b-12d3-a456-426614174000
                    external_id: doc-ext-002
                    workflow_type: AP
                    document_type: BILL
                    status: PENDING_REVIEW
                    counterparty:
                      id: 456e7890-e12b-34c5-d678-901234567890
                      type: vendor
                      display_name: Tech Services Ltd
                      external_id: vendor-001
                    reference_number: BILL-2024-001
                    reference_date: '2024-01-10'
                    due_date: '2024-02-09'
                    payment_terms: Net 30
                    currency: GBP
                    subtotal: 80000
                    tax_amount: 16000
                    total_amount: 96000
                    amount_paid: 0
                    amount_due: 96000
                    is_overdue: false
                    is_fully_paid: false
                    needs_review: true
                    review_reasons:
                    - low_extraction_confidence
                    - missing_line_item_accounts
                    reviewed_at: null
                    extraction_confidence: 0.72
                    classification_confidence: 0.88
                    line_items:
                    - id: 771e8400-e29b-41d4-a716-446655440000
                      financial_document_id: 661e8400-e29b-41d4-a716-446655440000
                      line_number: 1
                      description: Cloud hosting services - January 2024
                      sku: CLOUD-HOST-001
                      quantity: 1.0
                      unit_price: 80000
                      amount: 80000
                      tax_rate: 20.0
                      tax_amount: 16000
                      account_id: 234567ab-cdef-4567-8901-234567890123
                      account_code: '6100'
                      tracking_categories:
                        department: Engineering
                      metadata: {}
                    summary: null
                    source_document_id: 881e8400-e29b-41d4-a716-446655440000
                    document:
                      id: 881e8400-e29b-41d4-a716-446655440000
                      url: https://storage.example.com/presigned-url-def456
                      file_name: bill-tech-services-jan2024.pdf
                      expires_at: '2024-01-15T12:00:00Z'
                    journal_entry_id: null
                    posted_at: null
                    created_at: '2024-01-10T09:30:00Z'
                    updated_at: '2024-01-10T09:30:00Z'
                  summary: AP Bill
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    put:
      operationId: update_financial_document
      description: Update a financial document's reference fields and notes. Financial
        amounts cannot be changed directly - use correction workflows.
      summary: Update financial document
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: document_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this financial document.
        required: true
      tags:
      - Financial Documents
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FinancialDocumentUpdateAPIRequest'
            examples:
              UpdateRequest:
                value:
                  reference_number: INV-2024-001-REVISED
                  reference_date: '2024-01-15'
                  due_date: '2024-02-28'
                  payment_terms: Net 45
                  notes: Updated payment terms per customer request
                  metadata:
                    revision_reason: extended_terms
                    approved_by: finance_manager
                summary: Update Request
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FinancialDocumentUpdateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FinancialDocumentUpdateAPIRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinancialDocument'
              examples:
                UpdateResponse:
                  value:
                    type: FinancialDocumentData
                    id: 550e8400-e29b-41d4-a716-446655440000
                    business_id: 123e4567-e89b-12d3-a456-426614174000
                    external_id: doc-ext-001
                    workflow_type: AR
                    document_type: SALES_INVOICE
                    status: DRAFT
                    counterparty:
                      id: 789abcde-f234-5678-9012-345678901234
                      type: customer
                      display_name: Acme Corporation Ltd
                      external_id: cust-001
                    reference_number: INV-2024-001
                    reference_date: '2024-01-15'
                    due_date: '2024-02-14'
                    payment_terms: Net 30
                    currency: GBP
                    subtotal: 100000
                    tax_amount: 20000
                    total_amount: 120000
                    amount_paid: 0
                    amount_due: 120000
                    is_overdue: false
                    is_fully_paid: false
                    needs_review: false
                    review_reasons: []
                    reviewed_at: null
                    extraction_confidence: 0.95
                    classification_confidence: 0.92
                    line_items:
                    - id: 660e8400-e29b-41d4-a716-446655440000
                      financial_document_id: 550e8400-e29b-41d4-a716-446655440000
                      line_number: 1
                      description: Professional consulting services
                      sku: null
                      quantity: 10.0
                      unit_price: 10000
                      amount: 100000
                      tax_rate: 20.0
                      tax_amount: 20000
                      account_id: 234567ab-cdef-4567-8901-234567890123
                      account_code: '4000'
                      tracking_categories: {}
                      metadata: {}
                    summary: null
                    source_document_id: 770e8400-e29b-41d4-a716-446655440000
                    document:
                      id: 770e8400-e29b-41d4-a716-446655440000
                      url: https://storage.example.com/presigned-url-abc123
                      file_name: invoice-2024-001.pdf
                      expires_at: '2024-01-15T12:00:00Z'
                    journal_entry_id: null
                    posted_at: null
                    created_at: '2024-01-15T10:00:00Z'
                    updated_at: '2024-01-15T10:00:00Z'
                  summary: Update Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/financial-documents/{document_id}/mark-reviewed/:
    post:
      operationId: mark_financial_document_reviewed
      description: Mark a financial document as reviewed. This clears the needs_review
        flag and records the review timestamp.
      summary: Mark document as reviewed
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: document_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this financial document.
        required: true
      tags:
      - Financial Documents
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FinancialDocumentReviewActionRequest'
            examples:
              MarkReviewedRequest:
                value:
                  clear_review_reasons: true
                  notes: Reviewed and approved - all line items verified against source
                    document
                summary: Mark Reviewed Request
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FinancialDocumentReviewActionRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FinancialDocumentReviewActionRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinancialDocument'
              examples:
                MarkReviewedResponse:
                  value:
                    type: FinancialDocumentData
                    id: 550e8400-e29b-41d4-a716-446655440000
                    business_id: 123e4567-e89b-12d3-a456-426614174000
                    external_id: doc-ext-001
                    workflow_type: AR
                    document_type: SALES_INVOICE
                    status: DRAFT
                    counterparty:
                      id: 789abcde-f234-5678-9012-345678901234
                      type: customer
                      display_name: Acme Corporation Ltd
                      external_id: cust-001
                    reference_number: INV-2024-001
                    reference_date: '2024-01-15'
                    due_date: '2024-02-14'
                    payment_terms: Net 30
                    currency: GBP
                    subtotal: 100000
                    tax_amount: 20000
                    total_amount: 120000
                    amount_paid: 0
                    amount_due: 120000
                    is_overdue: false
                    is_fully_paid: false
                    needs_review: false
                    review_reasons: []
                    reviewed_at: null
                    extraction_confidence: 0.95
                    classification_confidence: 0.92
                    line_items:
                    - id: 660e8400-e29b-41d4-a716-446655440000
                      financial_document_id: 550e8400-e29b-41d4-a716-446655440000
                      line_number: 1
                      description: Professional consulting services
                      sku: null
                      quantity: 10.0
                      unit_price: 10000
                      amount: 100000
                      tax_rate: 20.0
                      tax_amount: 20000
                      account_id: 234567ab-cdef-4567-8901-234567890123
                      account_code: '4000'
                      tracking_categories: {}
                      metadata: {}
                    summary: null
                    source_document_id: 770e8400-e29b-41d4-a716-446655440000
                    document:
                      id: 770e8400-e29b-41d4-a716-446655440000
                      url: https://storage.example.com/presigned-url-abc123
                      file_name: invoice-2024-001.pdf
                      expires_at: '2024-01-15T12:00:00Z'
                    journal_entry_id: null
                    posted_at: null
                    created_at: '2024-01-15T10:00:00Z'
                    updated_at: '2024-01-15T10:00:00Z'
                  summary: Mark Reviewed Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/fixed-assets/:
    get:
      operationId: v1_platform_businesses_fixed_assets_list
      description: |-
        ViewSet for fixed asset CRUD operations.

        Endpoints:
        - GET    /businesses/{business_id}/fixed-assets/           List assets
        - POST   /businesses/{business_id}/fixed-assets/           Create asset
        - GET    /businesses/{business_id}/fixed-assets/{id}/      Get asset detail
        - PUT    /businesses/{business_id}/fixed-assets/{id}/      Update asset
        - DELETE /businesses/{business_id}/fixed-assets/{id}/      Delete asset
        - POST   /businesses/{business_id}/fixed-assets/{id}/depreciate/  Manual depreciation
        - POST   /businesses/{business_id}/fixed-assets/{id}/dispose/     Dispose asset
      parameters:
      - in: query
        name: acquisition_date_after
        schema:
          type: string
          format: date
      - in: query
        name: acquisition_date_before
        schema:
          type: string
          format: date
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: category
        schema:
          type: string
          x-spec-enum-id: 853bec44a2bd14ca
          enum:
          - buildings
          - computer_equipment
          - leasehold_improvements
          - machinery
          - office_furniture
          - other
          - software
          - vehicles
        description: |-
          Asset category for grouping and reporting

          * `computer_equipment` - Computer Equipment
          * `office_furniture` - Office Furniture & Equipment
          * `vehicles` - Vehicles
          * `machinery` - Machinery & Equipment
          * `buildings` - Buildings
          * `leasehold_improvements` - Leasehold Improvements
          * `software` - Software & Licenses
          * `other` - Other Fixed Assets
      - in: query
        name: status
        schema:
          type: string
          x-spec-enum-id: b474eebf8d73ba75
          enum:
          - active
          - disposed
          - fully_depreciated
        description: |-
          Current asset status

          * `active` - Active
          * `fully_depreciated` - Fully Depreciated
          * `disposed` - Disposed
      tags:
      - v1
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FixedAsset'
          description: ''
    post:
      operationId: v1_platform_businesses_fixed_assets_create
      description: |-
        ViewSet for fixed asset CRUD operations.

        Endpoints:
        - GET    /businesses/{business_id}/fixed-assets/           List assets
        - POST   /businesses/{business_id}/fixed-assets/           Create asset
        - GET    /businesses/{business_id}/fixed-assets/{id}/      Get asset detail
        - PUT    /businesses/{business_id}/fixed-assets/{id}/      Update asset
        - DELETE /businesses/{business_id}/fixed-assets/{id}/      Delete asset
        - POST   /businesses/{business_id}/fixed-assets/{id}/depreciate/  Manual depreciation
        - POST   /businesses/{business_id}/fixed-assets/{id}/dispose/     Dispose asset
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - v1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FixedAsset'
          description: ''
  /v1/platform/businesses/{business_id}/fixed-assets/{id}/:
    get:
      operationId: v1_platform_businesses_fixed_assets_retrieve
      description: |-
        ViewSet for fixed asset CRUD operations.

        Endpoints:
        - GET    /businesses/{business_id}/fixed-assets/           List assets
        - POST   /businesses/{business_id}/fixed-assets/           Create asset
        - GET    /businesses/{business_id}/fixed-assets/{id}/      Get asset detail
        - PUT    /businesses/{business_id}/fixed-assets/{id}/      Update asset
        - DELETE /businesses/{business_id}/fixed-assets/{id}/      Delete asset
        - POST   /businesses/{business_id}/fixed-assets/{id}/depreciate/  Manual depreciation
        - POST   /businesses/{business_id}/fixed-assets/{id}/dispose/     Dispose asset
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this fixed asset.
        required: true
      tags:
      - v1
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FixedAssetDetail'
          description: ''
    put:
      operationId: v1_platform_businesses_fixed_assets_update
      description: |-
        ViewSet for fixed asset CRUD operations.

        Endpoints:
        - GET    /businesses/{business_id}/fixed-assets/           List assets
        - POST   /businesses/{business_id}/fixed-assets/           Create asset
        - GET    /businesses/{business_id}/fixed-assets/{id}/      Get asset detail
        - PUT    /businesses/{business_id}/fixed-assets/{id}/      Update asset
        - DELETE /businesses/{business_id}/fixed-assets/{id}/      Delete asset
        - POST   /businesses/{business_id}/fixed-assets/{id}/depreciate/  Manual depreciation
        - POST   /businesses/{business_id}/fixed-assets/{id}/dispose/     Dispose asset
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this fixed asset.
        required: true
      tags:
      - v1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FixedAsset'
          description: ''
    patch:
      operationId: v1_platform_businesses_fixed_assets_partial_update
      description: |-
        ViewSet for fixed asset CRUD operations.

        Endpoints:
        - GET    /businesses/{business_id}/fixed-assets/           List assets
        - POST   /businesses/{business_id}/fixed-assets/           Create asset
        - GET    /businesses/{business_id}/fixed-assets/{id}/      Get asset detail
        - PUT    /businesses/{business_id}/fixed-assets/{id}/      Update asset
        - DELETE /businesses/{business_id}/fixed-assets/{id}/      Delete asset
        - POST   /businesses/{business_id}/fixed-assets/{id}/depreciate/  Manual depreciation
        - POST   /businesses/{business_id}/fixed-assets/{id}/dispose/     Dispose asset
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this fixed asset.
        required: true
      tags:
      - v1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedFixedAssetRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedFixedAssetRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedFixedAssetRequest'
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FixedAsset'
          description: ''
    delete:
      operationId: v1_platform_businesses_fixed_assets_destroy
      description: |-
        ViewSet for fixed asset CRUD operations.

        Endpoints:
        - GET    /businesses/{business_id}/fixed-assets/           List assets
        - POST   /businesses/{business_id}/fixed-assets/           Create asset
        - GET    /businesses/{business_id}/fixed-assets/{id}/      Get asset detail
        - PUT    /businesses/{business_id}/fixed-assets/{id}/      Update asset
        - DELETE /businesses/{business_id}/fixed-assets/{id}/      Delete asset
        - POST   /businesses/{business_id}/fixed-assets/{id}/depreciate/  Manual depreciation
        - POST   /businesses/{business_id}/fixed-assets/{id}/dispose/     Dispose asset
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this fixed asset.
        required: true
      tags:
      - v1
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '204':
          description: No response body
  /v1/platform/businesses/{business_id}/fixed-assets/{id}/depreciate/:
    post:
      operationId: v1_platform_businesses_fixed_assets_depreciate_create
      description: |-
        Manual depreciation action.

        POST /businesses/{business_id}/fixed-assets/{id}/depreciate/

        Body:
        {
            "period_date": "2024-06-01",  // optional, defaults to current month
            "force": false                // optional, force re-depreciation
        }

        Returns depreciation entry details.
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this fixed asset.
        required: true
      tags:
      - v1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FixedAsset'
          description: ''
  /v1/platform/businesses/{business_id}/fixed-assets/{id}/dispose/:
    post:
      operationId: v1_platform_businesses_fixed_assets_dispose_create
      description: |-
        Dispose asset action.

        POST /businesses/{business_id}/fixed-assets/{id}/dispose/

        Body:
        {
            "disposal_date": "2024-06-15",
            "disposal_reason": "sale",
            "disposal_proceeds_cents": 125000,  # In cents - €1250.00
            "buyer_name": "John Doe",
            "notes": "Sold to upgrade"
        }

        Returns disposal details with gain/loss.
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this fixed asset.
        required: true
      tags:
      - v1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/FixedAssetRequest'
        required: true
      security:
      - cookieAuth: []
      - basicAuth: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FixedAsset'
          description: ''
  /v1/platform/businesses/{business_id}/general-ledger/chart-of-accounts/:
    get:
      operationId: list_chart_of_accounts
      description: "\n        List all accounts with current balances for a business.\n\
        \n        **Features:**\n        - Filter by account type (Assets, Liabilities,\
        \ Equity, Revenue, Expenses)\n        - Filter by fiscal year (accounts with\
        \ activity in that year)\n        - Filter by specific accounting period (year\
        \ + month)\n        - Filter by parent account (hierarchical view)\n     \
        \   - Search by account name or code\n        - Include/exclude zero balance\
        \ accounts\n        - Group accounts by type (Assets, Liabilities, etc.)\n\
        \        - Pagination support (default: 20 per page, max: 100)\n\n       \
        \ **Response includes:**\n        - Account code, name, type, sub-type\n \
        \       - Current balance (from ledger)\n        - Formatted balance with\
        \ currency symbol (€, £, $)\n        - Period-specific balance (if period\
        \ filters applied)\n        - Debit and credit balances\n        - Parent/child\
        \ account relationships\n        - Hierarchy level and children indicator\n\
        \n        **Grouping:**\n        Use `group_by=type` to get accounts grouped\
        \ by:\n        - Assets (Current, Fixed, Other)\n        - Liabilities (Current,\
        \ Long-term)\n        - Equity\n        - Revenue\n        - Expenses (Operating,\
        \ COGS)\n\n        **Period Filtering:**\n        Use both `period_year` and\
        \ `period_month` together to get period-specific balances.\n        Example:\
        \ `period_year=2024&period_month=11` for November 2024.\n\n        **Account\
        \ Types (5 fundamental types):**\n        - `asset`: Asset (use account_subtype\
        \ for current/fixed/other)\n        - `liability`: Liability (use account_subtype\
        \ for current/long_term)\n        - `equity`: Equity\n        - `revenue`:\
        \ Revenue\n        - `expense`: Expense (use account_subtype for operating/cogs)\n\
        \        "
      summary: List chart of accounts
      parameters:
      - in: query
        name: account_type
        schema:
          type: string
        description: 'Filter by account type (case-insensitive). Values: asset, liability,
          equity, revenue, expense'
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: fiscal_year
        schema:
          type: integer
        description: 'Filter to show only accounts with journal entry activity in
          the specified fiscal year. Note: For export endpoint, use fiscal_year to
          calculate period-specific balances instead.'
      - in: query
        name: group_by
        schema:
          type: string
        description: 'Group accounts by category. Values: ''type'' (groups by Assets,
          Liabilities, Equity, Revenue, Expenses)'
      - in: query
        name: include_zero_balance
        schema:
          type: boolean
          default: true
        description: 'Include accounts with zero balance (default: true)'
      - in: query
        name: is_active
        schema:
          type: boolean
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1). Not used when group_by is specified.'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100). Not used when group_by
          is specified.'
      - in: query
        name: parent_account_id
        schema:
          type: string
          format: uuid
        description: Filter by parent account UUID (show sub-accounts only)
      - in: query
        name: period_month
        schema:
          type: integer
        description: Month for period-specific balance calculation (1-12). Must be
          used with period_year.
      - in: query
        name: period_year
        schema:
          type: integer
        description: Year for period-specific balance calculation (e.g., 2024). Must
          be used with period_month.
      - in: query
        name: search
        schema:
          type: string
        description: Search by account name, code, or institution name
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedChartOfAccountListList'
              examples:
                UKChartOfAccounts-BankAccount:
                  value:
                    count: 123
                    page_info:
                      total_count: 123
                      current_page: 1
                      total_pages: 7
                      page_size: 20
                    results:
                    - id: acc-1000-uuid
                      code: '1000'
                      name: Bank - Barclays Current
                      currency: GBP
                      account_type: asset
                      account_type_display: Asset
                      account_subtype: current_assets
                      account_subtype_display: Current Assets
                      parent_account_code: null
                      current_balance: 1250050
                      current_balance_formatted: £12,500.50
                      debit_balance: 1500000
                      credit_balance: 249950
                      period_balance: null
                      period_balance_formatted: null
                      has_children: false
                      hierarchy_level: 0
                      is_active: true
                  summary: UK Chart of Accounts - Bank Account
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: create_account
      description: "\n        Create a new account in the chart of accounts.\n\n \
        \       **Idempotency:** If external_id is provided and matches an existing\
        \ account,\n        returns the existing account with 200 OK.\n\n        **Parent\
        \ account:** Can be specified by UUID, code, or external_id.\n\n        **Accounting\
        \ validations:**\n        - is_non_cash_expense can only be set on expense\
        \ accounts\n        - balance_behavior must be 'debit_positive', 'credit_positive',\
        \ or blank\n        "
      summary: Create account
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - General Ledger
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountCreateAPIRequest'
            examples:
              CreateBankAccount:
                value:
                  code: '1100'
                  name: Business Bank Account
                  account_type: asset
                  account_subtype: current_assets
                  description: Primary operating bank account for daily transactions
                  external_id: qbo-1100
                  institution_name: Barclays Bank PLC
                  iban: GB29BUKB20201555555555
                  sort_code: 20-20-15
                  account_number_mask: '****5555'
                  is_cash_account: true
                  custom_fields:
                    branch: London City
                    relationship_manager: John Smith
                summary: Create bank account
              CreateWithParent:
                value:
                  code: 1100-01
                  name: Petty Cash
                  parent_id: '1100'
                  description: Office petty cash fund
                  external_id: qbo-1100-01
                  is_cash_account: true
                summary: Create with parent
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AccountCreateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AccountCreateAPIRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartOfAccountDetail'
              examples:
                AccountResponse:
                  value:
                    id: 234567ab-cdef-4567-8901-234567890123
                    code: '1100'
                    name: Business Bank Account
                    currency: GBP
                    account_type: asset
                    account_type_display: Asset
                    account_subtype: current_assets
                    account_subtype_display: Current Assets
                    parent_account_code: null
                    current_balance: 1250050
                    current_balance_formatted: £12,500.50
                    debit_balance: 1500000
                    credit_balance: 249950
                    has_children: true
                    hierarchy_level: 0
                    is_active: true
                    description: Primary operating bank account for daily transactions
                    institution_name: Barclays Bank PLC
                    iban: GB29BUKB20201555555555
                    sort_code: 20-20-15
                    account_number_mask: '****5555'
                    total_debits: 234
                    total_credits: 189
                    last_entry_date: '2024-03-28T14:30:00Z'
                    last_entry_reference: JE-2024-0042
                    sub_accounts: []
                  summary: Account response
          description: ''
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartOfAccountDetail'
              examples:
                AccountResponse:
                  value:
                    id: 234567ab-cdef-4567-8901-234567890123
                    code: '1100'
                    name: Business Bank Account
                    currency: GBP
                    account_type: asset
                    account_type_display: Asset
                    account_subtype: current_assets
                    account_subtype_display: Current Assets
                    parent_account_code: null
                    current_balance: 1250050
                    current_balance_formatted: £12,500.50
                    debit_balance: 1500000
                    credit_balance: 249950
                    has_children: true
                    hierarchy_level: 0
                    is_active: true
                    description: Primary operating bank account for daily transactions
                    institution_name: Barclays Bank PLC
                    iban: GB29BUKB20201555555555
                    sort_code: 20-20-15
                    account_number_mask: '****5555'
                    total_debits: 234
                    total_credits: 189
                    last_entry_date: '2024-03-28T14:30:00Z'
                    last_entry_reference: JE-2024-0042
                    sub_accounts: []
                  summary: Account response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/general-ledger/chart-of-accounts/{account_id}/:
    get:
      operationId: get_account_detail
      description: "\n        Get detailed information about a specific account by\
        \ ID, code, or external_id.\n\n        Includes:\n        - Full account information\n\
        \        - Current balance breakdown (debit/credit)\n        - Transaction\
        \ counts\n        - Sub-accounts (if any)\n        - Last transaction details\n\
        \        - Banking information (if bank account)\n\n        **Flexible lookup:**\
        \ The account_id parameter accepts UUID, account code, or external_id.\n \
        \       "
      summary: Get account detail
      parameters:
      - in: path
        name: account_id
        schema:
          type: string
        description: Account UUID, code, or external_id
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartOfAccountDetail'
              examples:
                UKBankAccountDetail:
                  value:
                    id: acc-1000-uuid
                    code: '1000'
                    name: Bank - Barclays Current
                    currency: GBP
                    account_type: asset
                    account_type_display: Asset
                    account_subtype: current_assets
                    account_subtype_display: Current Assets
                    parent_account_code: null
                    current_balance: 1250050
                    current_balance_formatted: £12,500.50
                    debit_balance: 1500000
                    credit_balance: 249950
                    period_balance: null
                    period_balance_formatted: null
                    has_children: false
                    hierarchy_level: 0
                    is_active: true
                    description: Primary business current account with Barclays
                    institution_name: Barclays Bank PLC
                    iban: GB29BUKB20201555555555
                    sort_code: 20-20-15
                    account_number_mask: '****5555'
                    total_debits: 234
                    total_credits: 189
                    last_entry_date: '2024-03-28T14:30:00Z'
                    last_entry_reference: JE-2024-0042
                    sub_accounts: []
                  summary: UK Bank Account Detail
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    patch:
      operationId: update_account
      description: "\n        Partial update of account fields.\n\n        **Editable\
        \ fields:** name, description, parent_id, is_active,\n        banking fields,\
        \ balance_behavior, custom_fields\n\n        **Non-editable:** code, account_type\n\
        \n        **Parent change validation:**\n        - New parent must have same\
        \ account_type\n        - Cannot create circular references\n\n        **Flexible\
        \ lookup:** The account_id parameter accepts UUID, account code, or external_id.\n\
        \        "
      summary: Update account (partial)
      parameters:
      - in: path
        name: account_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this account.
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - General Ledger
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedAccountUpdateAPIRequest'
            examples:
              UpdateAccount:
                value:
                  name: Main Business Account - Barclays
                  description: 'Updated: Primary operating bank account for all business
                    transactions'
                  institution_name: Barclays Bank UK PLC
                  custom_fields:
                    branch: London City
                    relationship_manager: Jane Doe
                    last_reviewed: '2024-03-15'
                summary: Update account
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedAccountUpdateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedAccountUpdateAPIRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartOfAccountDetail'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    delete:
      operationId: archive_account
      description: "\n        Archive an account (soft delete).\n\n        **Validations:**\n\
        \        - Cannot archive account with non-zero balance\n        - Cannot\
        \ archive account with active child accounts\n\n        Returns the archived\
        \ account with is_active set to false.\n\n        **Flexible lookup:** The\
        \ account_id parameter accepts UUID, account code, or external_id.\n     \
        \   "
      summary: Archive account (soft delete)
      parameters:
      - in: path
        name: account_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this account.
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartOfAccountDetail'
              examples:
                ArchivedAccountResponse:
                  value:
                    id: 234567ab-cdef-4567-8901-234567890123
                    code: '1100'
                    name: Business Bank Account
                    currency: GBP
                    account_type: asset
                    account_type_display: Asset
                    account_subtype: current_assets
                    account_subtype_display: Current Assets
                    parent_account_code: null
                    current_balance: 0
                    current_balance_formatted: £0.00
                    debit_balance: 0
                    credit_balance: 0
                    has_children: false
                    hierarchy_level: 0
                    is_active: false
                    description: Primary operating bank account for daily transactions
                    institution_name: Barclays Bank PLC
                    iban: GB29BUKB20201555555555
                    sort_code: 20-20-15
                    account_number_mask: '****5555'
                    total_debits: 234
                    total_credits: 189
                    last_entry_date: '2024-03-28T14:30:00Z'
                    last_entry_reference: JE-2024-0042
                    sub_accounts: []
                  summary: Archived account response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/general-ledger/chart-of-accounts/{account_id}/children/:
    post:
      operationId: create_child_account
      description: "\n        Create a child account under specified parent.\n\n \
        \       **Inherited from parent:**\n        - account_type\n        - account_subtype\n\
        \        - balance_behavior\n\n        **Required fields:**\n        - code:\
        \ Unique account code\n\n        Parent can be specified by UUID, code, or\
        \ external_id in the URL.\n        Supports idempotency via external_id field.\n\
        \        "
      summary: Create child account
      parameters:
      - in: path
        name: account_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this account.
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - General Ledger
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChildAccountCreateAPIRequest'
            examples:
              CreateChildAccount:
                value:
                  code: 1100-02
                  name: Savings Account
                  description: High-interest business savings account
                  external_id: qbo-1100-02
                  institution_name: Barclays Bank PLC
                  account_number_mask: '****6789'
                summary: Create child account
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ChildAccountCreateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ChildAccountCreateAPIRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartOfAccountDetail'
          description: ''
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartOfAccountDetail'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/general-ledger/chart-of-accounts/{account_id}/entries/:
    get:
      operationId: get_account_entries
      description: "\n        Returns paginated journal entry lines for the account\
        \ with running balance.\n\n        **Response includes:**\n        - opening_balance_cents:\
        \ Balance at start of period (or account inception)\n        - closing_balance_cents:\
        \ Balance at end of period (or current)\n        - Running balance per line\
        \ item\n        - Source document type for each entry\n\n        **Filtering:**\n\
        \        - start_date: Filter entries from this date (inclusive)\n       \
        \ - end_date: Filter entries up to this date (inclusive)\n        "
      summary: Get account journal entry lines
      parameters:
      - in: path
        name: account_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this account.
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: end_date
        schema:
          type: string
          format: date
        description: Filter entries up to this date (YYYY-MM-DD, inclusive)
      - in: query
        name: page
        schema:
          type: integer
        description: Page number (1-indexed)
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: start_date
        schema:
          type: string
          format: date
        description: Filter entries from this date (YYYY-MM-DD, inclusive)
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountEntriesResponse'
              examples:
                AccountEntriesResponse:
                  value:
                    account_id: 234567ab-cdef-4567-8901-234567890123
                    account_code: '1100'
                    account_name: Business Bank Account
                    opening_balance_cents: 1000000
                    closing_balance_cents: 1250050
                    total_debits_cents: 500000
                    total_credits_cents: 249950
                    entry_count: 15
                    entries:
                    - id: line-uuid-001
                      journal_entry_id: je-uuid-001
                      journal_entry_date: '2024-03-28'
                      journal_entry_reference: JE-2024-0042
                      journal_entry_description: Customer payment received
                      line_number: 1
                      debit_amount_cents: 54000
                      credit_amount_cents: 0
                      description: Payment from Acme Corp - Invoice INV-2024-001
                      external_reference: INV-2024-001
                      running_balance_cents: 1054000
                      source_type: invoice_payment
                      created_at: '2024-03-28T10:15:00Z'
                  summary: Account entries response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/general-ledger/chart-of-accounts/export/:
    get:
      operationId: export_chart_of_accounts
      description: "\n        Export chart of accounts to CSV format.\n\n        This\
        \ exports the same data as the hierarchy endpoint in a flat CSV format.\n\n\
        \        **CSV Columns:**\n        - Account Code\n        - Account Name\
        \ (indented by level)\n        - Account Type\n        - Account Subtype\n\
        \        - Current Balance (cents)\n        - Parent Code (parent account\
        \ code, empty for root accounts)\n        - Hierarchy Path (e.g., 1000 > 1001\
        \ > 1001-01)\n        - Level (hierarchy depth, 0 for root)\n        "
      summary: Export chart of accounts to CSV
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: string
                format: binary
          description: CSV file download
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/general-ledger/chart-of-accounts/hierarchy/:
    get:
      operationId: get_chart_of_accounts_hierarchy
      description: "\n        Returns all accounts organized in a hierarchical tree\
        \ structure.\n\n        **Features:**\n        - Returns only root accounts\
        \ (accounts with no parent) at the top level\n        - Each account includes\
        \ its children recursively\n        - Includes account_subtype for categorization\n\
        \        - Includes current balance for each account\n        - Calculates\
        \ hierarchy level for each account\n\n        **Response includes:**\n   \
        \     - hierarchy: List of root accounts with nested children\n        - total_accounts:\
        \ Total count of all accounts\n        "
      summary: Get accounts in hierarchical tree structure
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          description: Hierarchical tree of accounts
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/general-ledger/journal-entries/:
    get:
      operationId: list_journal_entries
      description: "\n        List all journal entries for a business with comprehensive\
        \ filtering.\n\n        **Features:**\n        - Filter by date range (date_from,\
        \ date_to)\n        - Filter by account (entries affecting a specific account)\n\
        \        - Filter by status (draft, approved, rejected)\n        - Filter\
        \ by created_by (ai, manual, system, import)\n        - Filter by posted status\n\
        \        - Search by description, reference, or sequence number\n        -\
        \ Pagination support (default: 20 per page, max: 100)\n\n        **Response\
        \ includes:**\n        - Entry sequence number, date, reference, description\n\
        \        - Total debit and credit amounts\n        - Balance status\n    \
        \    - Status and creation metadata\n        - Posted status and timestamp\n\
        \        - Source document type and reference (invoice, bill, payment, etc.)\n\
        \        "
      summary: List journal entries
      parameters:
      - in: query
        name: account_id
        schema:
          type: string
          format: uuid
        description: Filter entries affecting a specific account
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: created_by
        schema:
          type: string
        description: 'Filter by creator: ai, manual, system, import'
      - in: query
        name: date_from
        schema:
          type: string
          format: date
        description: Filter entries from this date (inclusive)
      - in: query
        name: date_to
        schema:
          type: string
          format: date
        description: Filter entries up to this date (inclusive)
      - in: query
        name: is_posted
        schema:
          type: boolean
        description: Filter by posted status
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: search
        schema:
          type: string
        description: Search by description, reference, or sequence number
      - in: query
        name: status
        schema:
          type: string
        description: 'Filter by status: draft, approved, rejected'
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedJournalEntryListList'
              examples:
                UKJournalEntry-CustomerInvoice:
                  value:
                    count: 123
                    page_info:
                      total_count: 123
                      current_page: 1
                      total_pages: 7
                      page_size: 20
                    results:
                    - id: je-uuid-001
                      sequence_number: JE-2024-0042
                      entry_date: '2024-03-28'
                      reference: INV-0042
                      description: Customer invoice for The Red Lion Pub Ltd
                      currency: GBP
                      total_debit: 540000
                      total_credit: 540000
                      is_balanced: true
                      created_by: system
                      created_by_display: System
                      status: approved
                      status_display: Approved
                      is_posted: true
                      posted_at: '2024-03-28T10:15:00Z'
                      bank_transaction_id: null
                      source_type: invoice
                      source_reference: INV-0042
                      created_at: '2024-03-28T10:10:00Z'
                  summary: UK Journal Entry - Customer Invoice
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/general-ledger/journal-entries/{entry_id}/:
    get:
      operationId: get_journal_entry_detail
      description: "\n        Get detailed information about a specific journal entry\
        \ including:\n        - Full entry information\n        - All debit/credit\
        \ lines with account details\n        - Accounting period information\n  \
        \      - Source information with linked documents (invoices, bills, payments,\
        \ etc.)\n        - Bank transaction details if reconciled\n        - Status\
        \ and audit trail\n        "
      summary: Get journal entry detail
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: path
        name: entry_id
        schema:
          type: string
          format: uuid
        description: Journal Entry UUID
        required: true
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JournalEntryDetail'
              examples:
                UKJournalEntryDetail-InvoiceWithVAT:
                  value:
                    id: je-uuid-001
                    sequence_number: JE-2024-0042
                    entry_date: '2024-03-28'
                    reference: INV-0042
                    description: Customer invoice for The Red Lion Pub Ltd
                    currency: GBP
                    total_debit: 540000
                    total_credit: 540000
                    is_balanced: true
                    created_by: system
                    created_by_display: System
                    status: approved
                    status_display: Approved
                    is_posted: true
                    posted_at: '2024-03-28T10:15:00Z'
                    bank_transaction_id: null
                    source_type: invoice
                    source_reference: INV-0042
                    created_at: '2024-03-28T10:10:00Z'
                    accounting_period:
                      id: period-uuid
                      year: 2024
                      month: 3
                      period_name: March 2024
                      status: open
                    lines:
                    - id: line-uuid-001
                      line_number: 1
                      account_code: '1200'
                      account_name: Accounts Receivable
                      account_type: asset
                      debit_amount: 540000
                      credit_amount: 0
                      description: Invoice INV-0042 - The Red Lion Pub Ltd
                      external_reference: INV-0042
                    - id: line-uuid-002
                      line_number: 2
                      account_code: '4000'
                      account_name: Sales Revenue
                      account_type: revenue
                      debit_amount: 0
                      credit_amount: 450000
                      description: Beer supply revenue
                      external_reference: INV-0042
                    - id: line-uuid-003
                      line_number: 3
                      account_code: '2200'
                      account_name: VAT Payable
                      account_type: liability
                      debit_amount: 0
                      credit_amount: 90000
                      description: VAT @ 20%
                      external_reference: INV-0042
                    source_info:
                      linked_documents:
                      - type: invoice
                        app_label: main
                        id: invoice-uuid
                        reference: INV-0042
                        display_name: Invoice INV-0042
                        created_at: '2024-03-28T10:00:00Z'
                        file_link:
                          url: https://s3.example.com/invoice.pdf?X-Amz-Signature=...
                          expires_in: 3600
                          document_id: document-uuid
                          file_name: Invoice_INV-0042.pdf
                          file_size: 12345
                          mime_type: application/pdf
                    rejection_reason: null
                    rejected_at: null
                    updated_at: '2024-03-28T10:15:00Z'
                  summary: UK Journal Entry Detail - Invoice with VAT
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/general-ledger/journal-entries/export/:
    get:
      operationId: export_journal_entries
      description: "\n        Export filtered journal entries to CSV format.\n\n \
        \       **Features:**\n        - Applies same filters as list endpoint\n \
        \       - Includes all entry details and line items\n        - Suitable for\
        \ Excel import\n        - Descriptive filename with business name and date\
        \ range\n\n        **CSV Columns:**\n        - Sequence Number, Entry Date,\
        \ Reference, Description\n        - Total Debit, Total Credit, Is Balanced\n\
        \        - Status, Created By, Posted At\n        - Account Code, Account\
        \ Name (for each line)\n        - Debit Amount, Credit Amount (for each line)\n\
        \        "
      summary: Export journal entries to CSV
      parameters:
      - in: query
        name: account_id
        schema:
          type: string
          format: uuid
        description: Filter entries affecting a specific account
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: created_by
        schema:
          type: string
        description: 'Filter by creator: ai, manual, system, import'
      - in: query
        name: date_from
        schema:
          type: string
          format: date
        description: Filter entries from this date (inclusive)
      - in: query
        name: date_to
        schema:
          type: string
          format: date
        description: Filter entries up to this date (inclusive)
      - in: query
        name: is_posted
        schema:
          type: boolean
        description: Filter by posted status
      - in: query
        name: search
        schema:
          type: string
        description: Search by description, reference, or sequence number
      - in: query
        name: status
        schema:
          type: string
        description: 'Filter by status: draft, approved, rejected'
      tags:
      - General Ledger
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: string
                format: binary
          description: CSV file download
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/insights/ap-aging/:
    get:
      operationId: get_ap_aging
      description: "\n        Retrieve AP aging analysis grouped by vendor.\n\n  \
        \      **Aging buckets:**\n        - Current: Not yet due (0 days overdue)\n\
        \        - 1-30 days: 1-30 days overdue\n        - 31-60 days: 31-60 days\
        \ overdue\n        - 61-90 days: 61-90 days overdue\n        - 90+ days: 90\
        \ or more days overdue\n\n        **Returns:**\n        - Total outstanding\
        \ across all vendors\n        - Total aging buckets (sum across all vendors)\n\
        \        - Per-vendor breakdown (sorted by total outstanding descending)\n\
        \n        All values are in cents. Currency is the business's base currency.\n\
        \        "
      summary: Get accounts payable aging
      parameters:
      - in: query
        name: as_of_date
        schema:
          type: string
          format: date
        description: Date to calculate aging as of (YYYY-MM-DD). Defaults to today.
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: group_by
        schema:
          type: string
          enum:
          - total
          - vendor
          default: vendor
        description: 'Grouping: ''vendor'' (default) or ''total'''
      tags:
      - Insights
      - Accounts Payable
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/APAging'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/insights/ar-aging/:
    get:
      operationId: get_ar_aging
      description: "\n        Retrieve AR aging analysis grouped by customer.\n\n\
        \        **Aging buckets:**\n        - Current: Not yet due (0 days overdue)\n\
        \        - 1-30 days: 1-30 days overdue\n        - 31-60 days: 31-60 days\
        \ overdue\n        - 61-90 days: 61-90 days overdue\n        - 90+ days: 90\
        \ or more days overdue\n\n        **Returns:**\n        - Total outstanding\
        \ across all customers\n        - Total aging buckets (sum across all customers)\n\
        \        - Per-customer breakdown (sorted by total outstanding descending)\n\
        \n        All values are in cents. Currency is the business's base currency.\n\
        \        "
      summary: Get accounts receivable aging
      parameters:
      - in: query
        name: as_of_date
        schema:
          type: string
          format: date
        description: Date to calculate aging as of (YYYY-MM-DD). Defaults to today.
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: group_by
        schema:
          type: string
          enum:
          - customer
          - total
          default: customer
        description: 'Grouping: ''customer'' (default) or ''total'''
      tags:
      - Insights
      - Accounts Receivable
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ARAging'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/insights/expense-breakdown/:
    get:
      operationId: get_expense_breakdown
      description: "\n        Retrieve detailed breakdown of expenses by category\
        \ with percentages.\n\n        **Categories:**\n        - Direct Costs: Cost\
        \ of goods sold\n        - Operating Expenses: Rent, salaries, utilities,\
        \ etc.\n        - Finance Costs: Interest expense, bank fees\n        - Income\
        \ Tax: Corporate tax\n\n        **Each category includes:**\n        - Total\
        \ amount in cents\n        - Percentage of total expenses\n        - Individual\
        \ GL accounts (sorted by amount descending)\n\n        Categories are sorted\
        \ by amount (largest first).\n        All values are in cents. Currency is\
        \ the business's base currency.\n        "
      summary: Get expense breakdown by category
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: end_date
        schema:
          type: string
          format: date
        description: Report period end date (YYYY-MM-DD)
        required: true
      - in: query
        name: start_date
        schema:
          type: string
          format: date
        description: Report period start date (YYYY-MM-DD)
        required: true
      tags:
      - Insights
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ExpenseBreakdown'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/insights/financial-summary/:
    get:
      operationId: get_financial_summary
      description: "\n        Retrieve financial summary with revenue, expenses, and\
        \ profit trends.\n\n        **Returns:**\n        - Overall summary: Total\
        \ revenue, expenses, and profit for the entire period\n        - Trends: Period-by-period\
        \ breakdown (monthly, quarterly, or yearly)\n\n        **Granularity options:**\n\
        \        - `monthly` (default): Show data per month\n        - `quarterly`:\
        \ Show data per quarter (Q1, Q2, Q3, Q4)\n        - `yearly`: Show data per\
        \ year\n\n        All values are in cents. Currency is the business's base\
        \ currency.\n        "
      summary: Get financial summary with trends
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: end_date
        schema:
          type: string
          format: date
        description: Report period end date (YYYY-MM-DD)
        required: true
      - in: query
        name: granularity
        schema:
          type: string
          enum:
          - monthly
          - quarterly
          - yearly
          default: monthly
        description: 'Period granularity: ''monthly'', ''quarterly'', or ''yearly'''
      - in: query
        name: start_date
        schema:
          type: string
          format: date
        description: Report period start date (YYYY-MM-DD)
        required: true
      tags:
      - Insights
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FinancialSummary'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/:
    get:
      operationId: list_invoices
      description: List all invoices for a business with comprehensive filtering options
        and standardized pagination
      summary: List invoices
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: query
        name: customer_external_id
        schema:
          type: string
        description: Filter by customer external ID
      - in: query
        name: customer_id
        schema:
          type: string
        description: Filter by customer ID (supports comma-separated UUIDs for multiple
          customers)
      - in: query
        name: due_at_end
        schema:
          type: string
          format: date-time
        description: Filter invoices due before this date (ISO format)
      - in: query
        name: due_at_start
        schema:
          type: string
          format: date-time
        description: Filter invoices due after this date (ISO format)
      - in: query
        name: max_amount
        schema:
          type: integer
        description: Maximum amount in cents
      - in: query
        name: memo
        schema:
          type: string
        description: Filter by exact memo text
      - in: query
        name: memo_contains
        schema:
          type: string
        description: Filter by memo containing text
      - in: query
        name: min_amount
        schema:
          type: integer
        description: Minimum amount in cents
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: reference_numbers
        schema:
          type: string
        description: Filter by reference numbers (comma-separated)
      - in: query
        name: search
        schema:
          type: string
      - in: query
        name: sent_at_end
        schema:
          type: string
          format: date-time
        description: Filter invoices sent before this date (ISO format)
      - in: query
        name: sent_at_start
        schema:
          type: string
          format: date-time
        description: Filter invoices sent after this date (ISO format)
      - in: query
        name: sort
        schema:
          type: string
          default: -imported_at
        description: 'Sort order. Values: imported_at, -imported_at, updated_at, -updated_at
          (prefix with - for descending)'
      - in: query
        name: status
        schema:
          type: string
        description: 'Filter by invoice status (comma-separated). Values: sent, paid,
          partially_paid, voided, refunded'
      tags:
      - Invoices
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedInvoiceList'
          description: ''
      x-audience:
      - partner
    post:
      operationId: create_invoice
      description: Create a new invoice for a business with line items and optional
        payments. Supports optional document upload via multipart field `file` (with
        optional document_type, upload_source, metadata, tags). JSON-only requests
        remain supported when no file is provided.
      summary: Create invoice
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      tags:
      - Invoices
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceCreateAPIRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/InvoiceCreateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InvoiceCreateAPIRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/{invoice_id}/:
    get:
      operationId: fetch_invoice
      description: Fetch a single invoice by ID for the specified business
      summary: Fetch invoice
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: invoice_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this invoice.
        required: true
      tags:
      - Invoices
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    put:
      operationId: update_invoice
      description: "\n        Update an existing invoice using PUT. Payments, refunds\
        \ and writeoffs are preserved.\n\n        **Update Rules:**\n        - Basic\
        \ fields (memo, external_id, invoice_number, due_date) can always be updated\n\
        \        - Customer and line items can only be changed if no payments/writeoffs\
        \ exist\n        - Invoices with status 'paid', 'refunded', 'written_off',\
        \ or 'voided' have limited update capabilities\n        - All financial calculations\
        \ are automatically recalculated when line items change\n\n        **Preserved\
        \ Data:**\n        - All payment allocations remain intact\n        - All\
        \ writeoff allocations remain intact\n        - All refund allocations remain\
        \ intact\n        - Invoice status is preserved (except automatic status updates)\n\
        \        - Accounting journal entries are preserved\n\n        Optional document\
        \ upload: send multipart with field `file` plus optional document_type, upload_source,\n\
        \        metadata, tags. JSON-only requests remain supported when no file\
        \ is provided.\n        "
      summary: Update invoice
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: invoice_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this invoice.
        required: true
      tags:
      - Invoices
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/InvoiceUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InvoiceUpdateRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/{invoice_id}/void/:
    post:
      operationId: void_invoice
      description: Void an existing invoice
      summary: Void invoice
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: invoice_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this invoice.
        required: true
      tags:
      - Invoices
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/InvoiceRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InvoiceRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/{invoice_id}/write-offs/:
    get:
      operationId: list_write_offs
      description: List all write-offs for a business, optionally filtered by invoice
        or status.
      summary: List write-offs
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: created_at_end
        schema:
          type: string
          format: date-time
      - in: query
        name: created_at_start
        schema:
          type: string
          format: date-time
      - in: query
        name: customer_id
        schema:
          type: array
          items:
            type: string
            format: uuid
        description: Multiple values may be separated by commas.
        explode: false
        style: form
      - in: query
        name: external_id
        schema:
          type: string
      - in: path
        name: invoice_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: invoice_id
        schema:
          type: array
          items:
            type: string
            format: uuid
        description: Multiple values may be separated by commas.
        explode: false
        style: form
      - in: query
        name: max_amount
        schema:
          type: number
        description: Maximum amount in cents
      - in: query
        name: min_amount
        schema:
          type: number
        description: Minimum amount in cents
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - in: query
        name: reason
        schema:
          type: string
      - in: query
        name: reference_number
        schema:
          type: string
      - in: query
        name: search
        schema:
          type: string
        description: Search in external ID, reference number, memo, customer name,
          and invoice number
      - in: query
        name: status
        schema:
          type: string
      - in: query
        name: write_off_at_end
        schema:
          type: string
          format: date-time
      - in: query
        name: write_off_at_start
        schema:
          type: string
          format: date-time
      tags:
      - Write-offs
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedWriteOffList'
              examples:
                UKPubBadDebtWrite-offResponse:
                  value:
                    count: 123
                    page_info:
                      total_count: 123
                      current_page: 1
                      total_pages: 7
                      page_size: 20
                    results:
                    - id: writeoff-uuid-001
                      invoice_id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                      external_id: writeoff-redlion-001
                      amount: 450000
                      memo: Invoice INV-0042 written off - customer ceased trading
                      destination_account:
                        type: AccountId
                        id: acc-bad-debt-expense
                      write_off_at: '2024-03-30T10:00:00Z'
                      transaction_tags:
                      - key: write_off_reason
                        value: ceased_trading
                      - key: customer_status
                        value: liquidated
                  summary: UK Pub Bad Debt Write-off Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: record_write_off
      description: Record a write-off of an invoice. If amount is omitted, defaults
        to the invoice's outstanding balance.
      summary: Record write-off
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: invoice_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Write-offs
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecordWriteOffRequestRequest'
            examples:
              UKPubBadDebtWrite-off:
                value:
                  external_id: writeoff-redlion-001
                  amount_cents: 450000
                  memo: Invoice INV-0042 written off - customer ceased trading
                  destination_account:
                    type: AccountId
                    id: acc-bad-debt-expense
                  write_off_at: '2024-03-30T10:00:00Z'
                  tags:
                  - key: write_off_reason
                    value: ceased_trading
                  - key: customer_status
                    value: liquidated
                summary: UK Pub Bad Debt Write-off
              PartialWrite-off(DisputeSettlement):
                value:
                  external_id: writeoff-partial-002
                  amount_cents: 150000
                  memo: Partial write-off - customer dispute settled at 66%
                  destination_account:
                    type: AccountId
                    id: acc-bad-debt-expense
                  tags:
                  - key: write_off_reason
                    value: dispute_settlement
                summary: Partial Write-off (Dispute Settlement)
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/RecordWriteOffRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/RecordWriteOffRequestRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WriteOff'
              examples:
                UKPubBadDebtWrite-offResponse:
                  value:
                    id: writeoff-uuid-001
                    invoice_id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                    external_id: writeoff-redlion-001
                    amount: 450000
                    memo: Invoice INV-0042 written off - customer ceased trading
                    destination_account:
                      type: AccountId
                      id: acc-bad-debt-expense
                    write_off_at: '2024-03-30T10:00:00Z'
                    transaction_tags:
                    - key: write_off_reason
                      value: ceased_trading
                    - key: customer_status
                      value: liquidated
                  summary: UK Pub Bad Debt Write-off Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/{invoice_id}/write-offs/{write_off_id}/:
    get:
      operationId: get_write_off
      description: Retrieve a single write-off by ID.
      summary: Get write-off
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: invoice_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: write_off_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this write off.
        required: true
      tags:
      - Write-offs
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WriteOff'
              examples:
                UKPubBadDebtWrite-offResponse:
                  value:
                    id: writeoff-uuid-001
                    invoice_id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                    external_id: writeoff-redlion-001
                    amount: 450000
                    memo: Invoice INV-0042 written off - customer ceased trading
                    destination_account:
                      type: AccountId
                      id: acc-bad-debt-expense
                    write_off_at: '2024-03-30T10:00:00Z'
                    transaction_tags:
                    - key: write_off_reason
                      value: ceased_trading
                    - key: customer_status
                      value: liquidated
                  summary: UK Pub Bad Debt Write-off Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    delete:
      operationId: delete_write_off
      description: Delete a write-off by ID.
      summary: Delete write-off
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: invoice_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: write_off_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this write off.
        required: true
      tags:
      - Write-offs
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WriteOff'
              examples:
                UKPubBadDebtWrite-offResponse:
                  value:
                    id: writeoff-uuid-001
                    invoice_id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                    external_id: writeoff-redlion-001
                    amount: 450000
                    memo: Invoice INV-0042 written off - customer ceased trading
                    destination_account:
                      type: AccountId
                      id: acc-bad-debt-expense
                    write_off_at: '2024-03-30T10:00:00Z'
                    transaction_tags:
                    - key: write_off_reason
                      value: ceased_trading
                    - key: customer_status
                      value: liquidated
                  summary: UK Pub Bad Debt Write-off Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/payments/:
    get:
      operationId: list_invoice_payments
      description: List all invoice payments for a business with filtering, pagination,
        and summary statistics.
      summary: List invoice payments
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: query
        name: customer_id
        schema:
          type: string
        description: Filter by customer ID (supports comma-separated UUIDs for multiple
          customers)
      - in: query
        name: date_from
        schema:
          type: string
          format: date-time
        description: Filter payments from this date/time (ISO format)
      - in: query
        name: date_to
        schema:
          type: string
          format: date-time
        description: Filter payments to this date/time (ISO format)
      - in: query
        name: fully_allocated
        schema:
          type: boolean
        description: Filter by allocation status (true=fully allocated, false=partially/unallocated)
      - in: query
        name: invoice_id
        schema:
          type: string
          format: uuid
        description: Filter by invoice ID (payments allocated to this invoice)
      - in: query
        name: max_amount
        schema:
          type: integer
        description: Maximum payment amount in cents (e.g., 100000 for €1000.00)
      - in: query
        name: method
        schema:
          type: string
        description: Filter by payment method
      - in: query
        name: min_amount
        schema:
          type: integer
        description: Minimum payment amount in cents (e.g., 10050 for €100.50)
      - in: query
        name: order
        schema:
          type: string
        description: 'Sort order (asc, desc). Default: desc'
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: processor
        schema:
          type: string
        description: Filter by payment processor
      - in: query
        name: search
        schema:
          type: string
        description: Search by payment reference, external_id, processor_reference,
          bank_reference, customer name, or notes
      - in: query
        name: sort
        schema:
          type: string
        description: 'Sort field (payment_date, amount, created_at). Default: payment_date'
      - in: query
        name: status
        schema:
          type: string
        description: Filter by payment status (pending, processing, completed, failed,
          cancelled, refunded)
      tags:
      - Invoice Payments
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedInvoicePaymentListList'
          description: ''
      x-audience:
      - partner
    post:
      operationId: create_invoice_payment
      description: Record a payment for one or more customer invoices. The payment
        is recorded and invoices are updated, ready to be matched during reconciliation
        later. Supports idempotency via Idempotency-Key header.
      summary: Create invoice payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      tags:
      - Invoice Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceRecordPaymentRequestRequest'
            examples:
              SimpleSingleInvoicePayment(UKPub):
                value:
                  customer_id: 4d90c3cc-1e55-5c61-9999-9ee36847163b
                  total_amount_cents: 450000
                  currency: GBP
                  payment_date: '2024-03-20'
                  payment_method: bank_transfer
                  payment_reference: PAY-2024-0042
                  references:
                    bank_reference: FPS-20240320-123456
                  note: Payment for INV-0042 - monthly beer supply
                  allocations:
                  - invoice_id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                    amount_cents: 450000
                summary: Simple Single Invoice Payment (UK Pub)
              Multi-InvoicePaymentWithPartialAllocation:
                value:
                  customer_id: 4d90c3cc-1e55-5c61-9999-9ee36847163b
                  total_amount_cents: 600000
                  currency: GBP
                  payment_date: '2024-03-22'
                  payment_method: card
                  payment_reference: PAY-2024-0043
                  references:
                    payment_reference: ch_3P1234567890AbCd
                  external_id: ext-payment-001
                  note: Payment for multiple outstanding invoices
                  metadata:
                    payment_source: online_portal
                    customer_ip: 192.0.2.1
                  allocations:
                  - invoice_id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                    amount_cents: 450000
                  - invoice_id: 6f90c3cc-3f77-7e83-bbbb-bff58069385d
                    amount_cents: 150000
                summary: Multi-Invoice Payment with Partial Allocation
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/InvoiceRecordPaymentRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InvoiceRecordPaymentRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentCreateResponse'
              examples:
                CreatePaymentResponse(UKPub):
                  value:
                    payment:
                      id: 7a80c3cc-4g88-8f94-cccc-cgg69180496e
                      business_id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                      customer_id: 4d90c3cc-1e55-5c61-9999-9ee36847163b
                      total_amount_cents: 450000
                      applied_amount_cents: 450000
                      allocated_amount_cents: 450000
                      unapplied_amount_cents: 0
                      remaining_amount_cents: 0
                      currency: GBP
                      status: completed
                      payment_method: bank_transfer
                      payment_reference: PAY-2024-0042
                      external_id: ext-payment-001
                      note: Payment for INV-0042 - monthly beer supply
                      bank_reference: FPS-20240320-123456
                      metadata: {}
                      idempotency_key: null
                      created_at: '2024-03-20T09:30:00Z'
                      updated_at: '2024-03-20T09:30:00Z'
                      applied_invoices:
                      - id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                        invoice_number: INV-0042
                        applied_amount_cents: 450000
                        status: paid
                        outstanding_amount_cents: 0
                  summary: Create Payment Response (UK Pub)
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/payments/{payment_id}/:
    get:
      operationId: get_invoice_payment
      description: Retrieve a single payment by ID with all its details and allocations.
      summary: Get invoice payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: payment_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this payment.
        required: true
      tags:
      - Invoice Payments
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoicePaymentList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    put:
      operationId: update_invoice_payment
      description: Update an existing payment's metadata, references, amounts, allocations,
        and status. Amount changes are validated to ensure they don't break existing
        allocations.
      summary: Update invoice payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: payment_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this payment.
        required: true
      tags:
      - Invoice Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePaymentRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UpdatePaymentRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UpdatePaymentRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentCreateResponse'
              examples:
                CreatePaymentResponse(UKPub):
                  value:
                    payment:
                      id: 7a80c3cc-4g88-8f94-cccc-cgg69180496e
                      business_id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                      customer_id: 4d90c3cc-1e55-5c61-9999-9ee36847163b
                      total_amount_cents: 450000
                      applied_amount_cents: 450000
                      allocated_amount_cents: 450000
                      unapplied_amount_cents: 0
                      remaining_amount_cents: 0
                      currency: GBP
                      status: completed
                      payment_method: bank_transfer
                      payment_reference: PAY-2024-0042
                      external_id: ext-payment-001
                      note: Payment for INV-0042 - monthly beer supply
                      bank_reference: FPS-20240320-123456
                      metadata: {}
                      idempotency_key: null
                      created_at: '2024-03-20T09:30:00Z'
                      updated_at: '2024-03-20T09:30:00Z'
                      applied_invoices:
                      - id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                        invoice_number: INV-0042
                        applied_amount_cents: 450000
                        status: paid
                        outstanding_amount_cents: 0
                  summary: Create Payment Response (UK Pub)
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    patch:
      operationId: partial_update_invoice_payment
      description: Partially update an existing payment's metadata, references, amounts,
        allocations, and status. Only provided fields will be updated. Amount changes
        are validated to ensure they don't break existing allocations.
      summary: Partially update invoice payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: payment_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this payment.
        required: true
      tags:
      - Invoice Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedUpdatePaymentRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedUpdatePaymentRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedUpdatePaymentRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentCreateResponse'
              examples:
                CreatePaymentResponse(UKPub):
                  value:
                    payment:
                      id: 7a80c3cc-4g88-8f94-cccc-cgg69180496e
                      business_id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                      customer_id: 4d90c3cc-1e55-5c61-9999-9ee36847163b
                      total_amount_cents: 450000
                      applied_amount_cents: 450000
                      allocated_amount_cents: 450000
                      unapplied_amount_cents: 0
                      remaining_amount_cents: 0
                      currency: GBP
                      status: completed
                      payment_method: bank_transfer
                      payment_reference: PAY-2024-0042
                      external_id: ext-payment-001
                      note: Payment for INV-0042 - monthly beer supply
                      bank_reference: FPS-20240320-123456
                      metadata: {}
                      idempotency_key: null
                      created_at: '2024-03-20T09:30:00Z'
                      updated_at: '2024-03-20T09:30:00Z'
                      applied_invoices:
                      - id: 5e90c3cc-2f66-6d72-aaaa-aff47958274c
                        invoice_number: INV-0042
                        applied_amount_cents: 450000
                        status: paid
                        outstanding_amount_cents: 0
                  summary: Create Payment Response (UK Pub)
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/payments/{payment_id}/delete/:
    post:
      operationId: delete_invoice_payment
      description: Cancel a payment and reverse its allocations. Only pending or failed
        payments can be deleted. Completed payments cannot be deleted - use refunds
        instead. This operation marks the payment as cancelled and updates invoice
        statuses.
      summary: Delete (cancel) invoice payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: payment_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this payment.
        required: true
      tags:
      - Invoice Payments
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoicePaymentDeleteResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/invoices/refunds/:
    get:
      operationId: list_refunds
      description: List refunds for a business with filtering and search.
      summary: List refunds
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: query
        name: completed_at_end
        schema:
          type: string
          format: date-time
        description: Filter refunds completed at or before this timestamp
      - in: query
        name: completed_at_start
        schema:
          type: string
          format: date-time
        description: Filter refunds completed at or after this timestamp
      - in: query
        name: customer_external_id
        schema:
          type: string
        description: Filter by customer external ID
      - in: query
        name: customer_id
        schema:
          type: string
        description: Filter by customer ID (supports comma-separated UUIDs for multiple
          customers)
      - in: query
        name: external_id
        schema:
          type: string
        description: Filter by external id
      - in: query
        name: is_dedicated
        schema:
          type: boolean
        description: Filter by dedicated flag
      - in: query
        name: max_amount
        schema:
          type: integer
        description: Maximum refunded amount in cents
      - in: query
        name: min_amount
        schema:
          type: integer
        description: Minimum refunded amount in cents
      - in: query
        name: ordering
        schema:
          type: string
        description: Ordering fields, e.g. -completed_at,-created_at
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: reference_numbers
        schema:
          type: string
        description: Comma-separated list of reference numbers
      - in: query
        name: search
        schema:
          type: string
        description: Search in external_id, reference_number, memo, customer name
      - in: query
        name: status
        schema:
          type: string
        description: Comma-separated statuses (pending,processing,paid,failed,cancelled)
      tags:
      - Refunds
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedRefundList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: create_refund
      description: Create a simple refund for an invoice. Provide partial_amount to
        create a partial refund.
      summary: Create refund (full or partial)
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      tags:
      - Refunds
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSimpleRefundRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateSimpleRefundRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateSimpleRefundRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refund'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/refunds/{refund_id}/:
    get:
      operationId: get_refund
      description: Retrieve a single refund by ID with all payments and allocations.
      summary: Get refund
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this refund.
        required: true
      tags:
      - Refunds
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refund'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    put:
      operationId: update_refund
      description: Update refund details including memo, reference number, metadata,
        and optionally upload a document.
      summary: Update refund
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: Refund UUID
        required: true
      tags:
      - Refunds
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefundUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/RefundUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/RefundUpdateRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refund'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    patch:
      operationId: partial_update_refund
      description: Partially update refund details including memo, reference number,
        metadata, and optionally upload a document.
      summary: Partially update refund
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: Refund UUID
        required: true
      tags:
      - Refunds
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedRefundUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedRefundUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedRefundUpdateRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refund'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    delete:
      operationId: delete_refund
      description: Delete refund
      summary: Delete refund
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID provided by Thred (unique identifier for the business)
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this refund.
        required: true
      tags:
      - Refunds
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          description: Deleted
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/refunds/{refund_id}/allocations/{allocation_id}/:
    delete:
      operationId: delete_refund_allocation
      description: |-
        Unlink an invoice from a refund by deleting the allocation.

        This removes the association between the refund and the invoice without affecting the refund itself or its journal entries. The refund's unallocated amount will increase, and the invoice's refundable amount will increase accordingly.
      summary: Delete refund allocation
      parameters:
      - in: path
        name: allocation_id
        schema:
          type: string
          format: uuid
        description: Allocation UUID
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: Refund UUID
        required: true
      tags:
      - Refund Allocations
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: Allocation deleted successfully
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/refunds/{refund_id}/payments/:
    get:
      operationId: list_refund_payments
      description: List all payments recorded for a refund, newest first. Supports
        pagination.
      summary: List refund payments
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business ID
        required: true
        examples:
          BusinessID:
            value: 123e4567-e89b-12d3-a456-426614174000
            summary: Business ID
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: Refund ID
        required: true
        examples:
          RefundID:
            value: 7890abcd-1234-5678-90ab-cdef12345678
            summary: Refund ID
      tags:
      - Refund Payments
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedRefundPaymentList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: create_refund_payment
      description: |-
        Create a payment for an existing refund. Supports idempotency via external_id.
        - Amount must not exceed remaining refundable amount.
        - Status transitions: pending→processing (partial), →paid (fully covered).
      summary: Create refund payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Refund Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateRefundPaymentRequestRequest'
            examples:
              CreateRefundPayment:
                value:
                  amount_cents: 20000
                  method: ACH
                  completed_at: '2026-02-13T10:58:03.887570Z'
                  external_id: rp-2024-001
                  processor: STRIPE
                  memo: Partial refund transfer
                  transaction_tags:
                  - refund_batch:2024-01
                  - channel:bank
                  refund_processing_fee_cents: 30
                summary: Create Refund Payment
                description: Example request payload to create a refund payment
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateRefundPaymentRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateRefundPaymentRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RefundPayment'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/invoices/refunds/{refund_id}/payments/{payment_id}/:
    get:
      operationId: fetch_refund_payment
      description: Retrieve a single refund payment by ID with all details and reconciliation
        information.
      summary: Fetch refund payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: payment_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this refund payment.
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Refund Payments
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RefundPayment'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    delete:
      operationId: delete_refund_payment
      description: Delete refund payment and update refund status
      summary: Delete refund payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: payment_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this refund payment.
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Refund Payments
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          description: Deleted
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/link-accounts/:
    post:
      operationId: link_accounts
      description: Activate selected accounts and deactivate others
      summary: Link Accounts
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Plaid Integration APIs
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountLinkingRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AccountLinkingRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/AccountLinkingRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountLinkingResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/menu-config/:
    get:
      operationId: get_menu_config
      description: "\n        Retrieve the effective menu configuration for a business.\n\
        \n        Returns the business-specific configuration if set, otherwise returns\n\
        \        the partner's default configuration.\n\n        The response includes\
        \ a 'source' field indicating whether the config\n        is business-specific\
        \ or inherited from the partner.\n        "
      summary: Get menu configuration
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Menu Configuration
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MenuConfig'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    put:
      operationId: update_menu_config
      description: "\n        Update the menu configuration for a specific business.\n\
        \n        This creates or updates a business-specific override of the partner's\n\
        \        default configuration. Only the menu items provided will be set;\n\
        \        you can provide a partial configuration.\n\n        Admin-only operation.\n\
        \        "
      summary: Update menu configuration
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Menu Configuration
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateMenuConfigRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UpdateMenuConfigRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UpdateMenuConfigRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MenuConfig'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    delete:
      operationId: delete_menu_config
      description: "\n        Delete the business-specific menu configuration.\n\n\
        \        After deletion, the business will inherit the partner's default\n\
        \        configuration. This operation is idempotent.\n\n        Admin-only\
        \ operation.\n        "
      summary: Reset menu configuration
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Menu Configuration
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/payouts/:
    get:
      operationId: list_payouts
      description: List all payouts within a business. Supports filtering by processor,
        status, date range, and search capabilities. Returns paginated results with
        standardized pagination.
      summary: List payouts
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID (unique identifier for the business)
        required: true
      - in: query
        name: completed_at_end
        schema:
          type: string
          format: date-time
        description: Filter payouts completed to this date/time
      - in: query
        name: completed_at_start
        schema:
          type: string
          format: date-time
        description: Filter payouts completed from this date/time
      - in: query
        name: external_id
        schema:
          type: string
        description: Filter by external ID (partial match, case-insensitive)
      - in: query
        name: max_amount
        schema:
          type: integer
        description: Maximum payout amount in cents
      - in: query
        name: min_amount
        schema:
          type: integer
        description: Minimum payout amount in cents
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (1-indexed, default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Number of items per page (default: 20, max: 100)'
      - in: query
        name: processor
        schema:
          type: string
        description: Filter by payment processor (stripe, adyen, paypal, etc.)
      - in: query
        name: reconciliation_status
        schema:
          type: string
        description: Filter by reconciliation status (unreconciled, partially_reconciled,
          fully_reconciled)
      - in: query
        name: search
        schema:
          type: string
        description: Search by external_id, reference_number, memo, or processor_payout_id
      - in: query
        name: status
        schema:
          type: string
        description: Filter by payout status
      tags:
      - Payouts
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedPayoutListList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: create_payout
      description: Create a new payout or update an existing one via external_id.
        Partners send completed processor settlements (Stripe, Adyen, etc.) with associated
        invoice payments and refund payments. Returns 201 for new payouts, 200 for
        updates. Updates are blocked if payout is already reconciled to a bank transaction.
      summary: Create or update a payout
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID (unique identifier for the business)
        required: true
      tags:
      - Payouts
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PayoutCreateRequest'
            examples:
              StripePayoutExample:
                value:
                  external_id: stripe_po_2024_12_20
                  processor: stripe
                  processor_payout_id: po_1OeYZb2eZvKYlo2C6KqhQWxE
                  paid_out_amount_cents: 920000
                  fee_cents: 30000
                  additional_refunds_amount_cents: 0
                  currency: GBP
                  status: paid
                  completed_at: '2024-12-20T14:30:45Z'
                  payment_ids:
                  - 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                  - 4d81d4dd-9d14-5d2b-ad8b-9f6dad4c5g3e
                  refund_payment_ids:
                  - 5e92e5ee-ae25-6e3c-be9c-ag7ebe5d6h4f
                  reference_number: PAYOUT-2024-W51
                  memo: Weekly Stripe settlement
                  metadata:
                    batch_id: w51
                    settlement_period: 2024-12-14_to_2024-12-20
                summary: Stripe Payout Example
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PayoutCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PayoutCreateRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutResponse'
              examples:
                PayoutResponse:
                  value:
                    id: be90c3cc-7d18-4e2d-8e6e-9f5d7e4a5c3b
                    business_id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                    external_id: stripe_po_2024_12_20
                    processor: stripe
                    processor_payout_id: po_1OeYZb2eZvKYlo2C6KqhQWxE
                    paid_out_amount_cents: 920000
                    fee_cents: 30000
                    additional_refunds_amount_cents: 0
                    net_amount_cents: 890000
                    currency: GBP
                    status: paid
                    completed_at: '2024-12-20T14:30:45Z'
                    imported_at: '2024-12-20T15:00:12Z'
                    reference_number: PAYOUT-2024-W51
                    memo: Weekly Stripe settlement
                    metadata:
                      batch_id: w51
                    payment_count: 2
                    refund_payment_count: 1
                    gross_payments_amount_cents: 1000000
                    total_refunds_amount_cents: 50000
                    expected_net_amount_cents: 920000
                    amount_variance_cents: 0
                    payments:
                    - id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                      external_id: stripe_pi_xyz123
                      payment_reference: PAY-2024-0042
                      customer_name: The Red Lion Pub Ltd
                      payment_date: '2024-12-15'
                      total_amount_cents: 450000
                      currency: GBP
                    refund_payments:
                    - id: 5e92e5ee-ae25-6e3c-be9c-ag7ebe5d6h4f
                      external_id: stripe_re_abc456
                      refund_id: 6f03f6ff-bf36-7f4d-cf0d-bh8fcf6e7i5g
                      customer_name: The Red Lion Pub Ltd
                      refunded_amount_cents: 50000
                      completed_at: '2024-12-16T10:00:00Z'
                    reconciliation_status: unreconciled
                    settlement_file_id: null
                    created_at: '2024-12-20T15:00:12Z'
                    updated_at: '2024-12-20T15:00:12Z'
                  summary: Payout Response
          description: ''
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutResponse'
              examples:
                PayoutResponse:
                  value:
                    id: be90c3cc-7d18-4e2d-8e6e-9f5d7e4a5c3b
                    business_id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                    external_id: stripe_po_2024_12_20
                    processor: stripe
                    processor_payout_id: po_1OeYZb2eZvKYlo2C6KqhQWxE
                    paid_out_amount_cents: 920000
                    fee_cents: 30000
                    additional_refunds_amount_cents: 0
                    net_amount_cents: 890000
                    currency: GBP
                    status: paid
                    completed_at: '2024-12-20T14:30:45Z'
                    imported_at: '2024-12-20T15:00:12Z'
                    reference_number: PAYOUT-2024-W51
                    memo: Weekly Stripe settlement
                    metadata:
                      batch_id: w51
                    payment_count: 2
                    refund_payment_count: 1
                    gross_payments_amount_cents: 1000000
                    total_refunds_amount_cents: 50000
                    expected_net_amount_cents: 920000
                    amount_variance_cents: 0
                    payments:
                    - id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                      external_id: stripe_pi_xyz123
                      payment_reference: PAY-2024-0042
                      customer_name: The Red Lion Pub Ltd
                      payment_date: '2024-12-15'
                      total_amount_cents: 450000
                      currency: GBP
                    refund_payments:
                    - id: 5e92e5ee-ae25-6e3c-be9c-ag7ebe5d6h4f
                      external_id: stripe_re_abc456
                      refund_id: 6f03f6ff-bf36-7f4d-cf0d-bh8fcf6e7i5g
                      customer_name: The Red Lion Pub Ltd
                      refunded_amount_cents: 50000
                      completed_at: '2024-12-16T10:00:00Z'
                    reconciliation_status: unreconciled
                    settlement_file_id: null
                    created_at: '2024-12-20T15:00:12Z'
                    updated_at: '2024-12-20T15:00:12Z'
                  summary: Payout Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/payouts/{payout_id}/:
    get:
      operationId: get_payout
      description: Get detailed information about a specific payout, including expanded
        payment and refund payment arrays.
      summary: Get a payout
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID (unique identifier for the business)
        required: true
      - in: path
        name: payout_id
        schema:
          type: string
          format: uuid
        description: Payout UUID
        required: true
      tags:
      - Payouts
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutResponse'
              examples:
                PayoutResponse:
                  value:
                    id: be90c3cc-7d18-4e2d-8e6e-9f5d7e4a5c3b
                    business_id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                    external_id: stripe_po_2024_12_20
                    processor: stripe
                    processor_payout_id: po_1OeYZb2eZvKYlo2C6KqhQWxE
                    paid_out_amount_cents: 920000
                    fee_cents: 30000
                    additional_refunds_amount_cents: 0
                    net_amount_cents: 890000
                    currency: GBP
                    status: paid
                    completed_at: '2024-12-20T14:30:45Z'
                    imported_at: '2024-12-20T15:00:12Z'
                    reference_number: PAYOUT-2024-W51
                    memo: Weekly Stripe settlement
                    metadata:
                      batch_id: w51
                    payment_count: 2
                    refund_payment_count: 1
                    gross_payments_amount_cents: 1000000
                    total_refunds_amount_cents: 50000
                    expected_net_amount_cents: 920000
                    amount_variance_cents: 0
                    payments:
                    - id: 3c90c3cc-8c03-4c1a-9c7a-8e5c9a3b4f2d
                      external_id: stripe_pi_xyz123
                      payment_reference: PAY-2024-0042
                      customer_name: The Red Lion Pub Ltd
                      payment_date: '2024-12-15'
                      total_amount_cents: 450000
                      currency: GBP
                    refund_payments:
                    - id: 5e92e5ee-ae25-6e3c-be9c-ag7ebe5d6h4f
                      external_id: stripe_re_abc456
                      refund_id: 6f03f6ff-bf36-7f4d-cf0d-bh8fcf6e7i5g
                      customer_name: The Red Lion Pub Ltd
                      refunded_amount_cents: 50000
                      completed_at: '2024-12-16T10:00:00Z'
                    reconciliation_status: unreconciled
                    settlement_file_id: null
                    created_at: '2024-12-20T15:00:12Z'
                    updated_at: '2024-12-20T15:00:12Z'
                  summary: Payout Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    delete:
      operationId: delete_payout
      description: Delete a payout if it is not reconciled to a bank transaction.
        This will unlink all associated payments and refund payments, making them
        available for other payouts. Blocked if payout is reconciled.
      summary: Delete a payout
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID (unique identifier for the business)
        required: true
      - in: path
        name: payout_id
        schema:
          type: string
          format: uuid
        description: Payout UUID
        required: true
      tags:
      - Payouts
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  deleted:
                    type: boolean
                example:
                  deleted: true
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/receipts/:
    get:
      operationId: list_receipts
      description: List all receipts for a business with filters for vendor, dates,
        amounts, payment method, and reconciliation status. Supports standardized
        pagination.
      summary: List receipts
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: currency
        schema:
          type: string
        description: Filter by currency code
      - in: query
        name: is_reconciled
        schema:
          type: boolean
        description: Filter by reconciliation status (true/false)
      - in: query
        name: max_amount
        schema:
          type: integer
        description: Maximum total amount in cents
      - in: query
        name: min_amount
        schema:
          type: integer
        description: Minimum total amount in cents
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (1-indexed, default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Number of items per page (default: 20, max: 100)'
      - in: query
        name: payment_method
        schema:
          type: string
        description: Filter by payment method (cash, credit_card, debit_card, bank_transfer,
          check, other)
      - in: query
        name: receipt_date_end
        schema:
          type: string
          format: date-time
        description: Receipts dated on/before this timestamp (ISO format)
      - in: query
        name: receipt_date_start
        schema:
          type: string
          format: date-time
        description: Receipts dated on/after this timestamp (ISO format)
      - in: query
        name: receipt_number
        schema:
          type: string
        description: Search by receipt number (case-insensitive substring match)
      - in: query
        name: search
        schema:
          type: string
        description: Search in receipt number, external ID, description, and vendor
          name
      - in: query
        name: sort
        schema:
          type: string
          default: -created_at
        description: 'Sort order. Values: created_at, -created_at, updated_at, -updated_at
          (prefix with - for descending)'
      - in: query
        name: vendor_external_id
        schema:
          type: string
        description: Filter by vendor external ID
      - in: query
        name: vendor_id
        schema:
          type: string
        description: Filter by vendor ID (supports comma-separated UUIDs for multiple
          vendors)
      tags:
      - Receipts
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedReceiptList'
          description: ''
    post:
      operationId: create_receipt
      description: Create a new receipt for a business. Supports idempotency via external_id.
      summary: Create receipt
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Receipts
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReceiptCreateAPIRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ReceiptCreateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ReceiptCreateAPIRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Receipt'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/receipts/{receipt_id}/:
    get:
      operationId: get_receipt
      description: Retrieve a single receipt by ID for the specified business.
      summary: Get receipt
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business ID
        required: true
      - in: path
        name: receipt_id
        schema:
          type: string
          format: uuid
        description: Receipt ID
        required: true
      tags:
      - Receipts
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Receipt'
          description: ''
    put:
      operationId: update_receipt
      description: Update receipt via PUT.
      summary: Update receipt
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: receipt_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this receipt.
        required: true
      tags:
      - Receipts
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReceiptUpdateAPIRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ReceiptUpdateAPIRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ReceiptUpdateAPIRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Receipt'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    delete:
      operationId: delete_receipt
      description: Soft delete a receipt. The receipt will be marked as deleted but
        not removed from the database.
      summary: Delete receipt
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: receipt_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this receipt.
        required: true
      tags:
      - Receipts
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/receipts/{receipt_id}/reconcile/:
    post:
      operationId: reconcile_receipt
      description: Link this receipt to a bank transaction for reconciliation. This
        creates a ReconciliationLink between the receipt and bank transaction.
      summary: Reconcile receipt to bank transaction
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: receipt_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this receipt.
        required: true
      tags:
      - Reconciliation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReceiptReconciliationRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ReceiptReconciliationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ReceiptReconciliationRequestRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/receipts/{receipt_id}/reconciliations/:
    get:
      operationId: list_receipt_reconciliations
      description: Get all bank transaction reconciliations for this receipt.
      summary: List all reconciliations for this receipt
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: receipt_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this receipt.
        required: true
      tags:
      - Receipts
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReceiptReconciliationList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/receipts/{receipt_id}/unreconcile/:
    post:
      operationId: unreconcile_receipt
      description: Remove reconciliation link between receipt and bank transaction.
      summary: Remove receipt reconciliation
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: receipt_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this receipt.
        required: true
      tags:
      - UnReconciliation
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                bank_transaction_id:
                  type: string
                  format: uuid
              required:
              - bank_transaction_id
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnreconciliationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/reports/balance-sheet/:
    get:
      operationId: get_balance_sheet
      description: "\n        Retrieve a Balance Sheet report for a business as of\
        \ a specific date.\n\n        **Important:** Both posted and draft journal\
        \ entries are included in the calculations.\n\n        **Summary metrics returned:**\n\
        \        - total_assets_cents: Non-current Assets + Current Assets\n     \
        \   - total_non_current_assets_cents: Sum of Non-current Assets subtype\n\
        \        - total_current_assets_cents: Sum of Current Assets subtype\n   \
        \     - total_liabilities_cents: Current Liabilities + Non-current Liabilities\n\
        \        - total_current_liabilities_cents: Sum of Current Liabilities subtype\n\
        \        - total_non_current_liabilities_cents: Sum of Non-current Liabilities\
        \ subtype\n        - total_equity_cents: Share Capital + Share Premium + Reserves\
        \ + Retained Earnings (+ current period P&L)\n        - net_assets_cents:\
        \ Total Assets - Total Liabilities (equals Total Equity)\n\n        **Retained\
        \ Earnings includes:**\n        - Historical retained earnings from RETAINED_EARNINGS\
        \ accounts\n        - Current fiscal period P&L (auto-calculated from revenue/expense\
        \ accounts)\n\n        **Detail levels:**\n        - `summary` (default):\
        \ Returns only summary metrics\n        - `detailed`: Returns summary + line\
        \ item breakdown by AccountSubtype\n\n        All values are in cents. Currency\
        \ is the business's base currency.\n        "
      summary: Get balance sheet report
      parameters:
      - in: query
        name: as_of_date
        schema:
          type: string
          format: date
        description: Balance sheet date - point in time (YYYY-MM-DD)
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: detail_level
        schema:
          type: string
          enum:
          - detailed
          - summary
          default: summary
        description: 'Level of detail: ''summary'' or ''detailed'''
      tags:
      - Reports
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BalanceSheet'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/reports/cash-flow/:
    get:
      operationId: get_cash_flow_statement
      description: "\n        Retrieve a Cash Flow Statement (Indirect Method) for\
        \ a business within a date range.\n\n        **Important:** Both posted and\
        \ draft journal entries are included in the calculations.\n\n        **Cash\
        \ Flow Sections:**\n        - **Operating Activities**: Net profit + Non-cash\
        \ adjustments + Working capital changes\n        - **Investing Activities**:\
        \ Changes in non-current assets (PPE, intangibles)\n        - **Financing\
        \ Activities**: Changes in equity and long-term debt\n\n        **Summary\
        \ metrics returned:**\n        - net_cash_from_operating_cents: Cash flow\
        \ from operating activities\n        - net_cash_from_investing_cents: Cash\
        \ flow from investing activities\n        - net_cash_from_financing_cents:\
        \ Cash flow from financing activities\n        - net_change_in_cash_cents:\
        \ Total change in cash position\n        - opening_cash_cents: Cash balance\
        \ at period start\n        - closing_cash_cents: Cash balance at period end\n\
        \n        **Cash Reconciliation:**\n        The report includes a reconciliation\
        \ to verify:\n        Opening Cash + Net Change = Closing Cash\n\n       \
        \ **Detail levels:**\n        - `summary` (default): Returns only summary\
        \ metrics + reconciliation\n        - `detailed`: Returns summary + line item\
        \ breakdown by account\n\n        **Key filters:**\n        - Cash accounts:\
        \ Accounts where is_cash_account=True\n        - Non-cash expenses: Accounts\
        \ where is_non_cash_expense=True (depreciation, etc.)\n        - Working capital:\
        \ Current assets (excl. cash) and current liabilities\n\n        All values\
        \ are in cents. Currency is the business's base currency.\n\n        Accounting\
        \ standards validated: IAS 7, ASC 230, FRS 102, RJ 360\n        "
      summary: Get cash flow statement
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: detail_level
        schema:
          type: string
          enum:
          - detailed
          - summary
          default: summary
        description: 'Level of detail: ''summary'' or ''detailed'''
      - in: query
        name: end_date
        schema:
          type: string
          format: date
        description: Report period end date (YYYY-MM-DD)
        required: true
      - in: query
        name: start_date
        schema:
          type: string
          format: date
        description: Report period start date (YYYY-MM-DD)
        required: true
      tags:
      - Reports
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CashFlowStatement'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/reports/profit-and-loss/:
    get:
      operationId: get_profit_and_loss
      description: "\n        Retrieve a Profit and Loss report for a business within\
        \ a date range.\n\n        **Important:** Both posted and draft journal entries\
        \ are included in the calculations.\n\n        **Summary metrics returned:**\n\
        \        - net_revenue_cents: Sum of Revenue subtype accounts\n        - total_operating_income_cents:\
        \ Net revenue + Other Operating Income\n        - gross_profit_cents: Total\
        \ operating income - Direct Costs\n        - operating_profit_cents: Gross\
        \ profit - Operating Expenses\n        - profit_before_tax_cents: Operating\
        \ profit + Finance Income - Finance Costs\n        - net_profit_cents: Profit\
        \ before tax - Income Tax\n\n        **Detail levels:**\n        - `summary`\
        \ (default): Returns only summary metrics\n        - `detailed`: Returns summary\
        \ + line item breakdown by AccountSubtype\n\n        All values are in cents.\
        \ Currency is the business's base currency.\n        "
      summary: Get profit and loss report
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: query
        name: detail_level
        schema:
          type: string
          enum:
          - detailed
          - summary
          default: summary
        description: 'Level of detail: ''summary'' or ''detailed'''
      - in: query
        name: end_date
        schema:
          type: string
          format: date
        description: Report period end date (YYYY-MM-DD)
        required: true
      - in: query
        name: start_date
        schema:
          type: string
          format: date
        description: Report period start date (YYYY-MM-DD)
        required: true
      tags:
      - Reports
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProfitAndLoss'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/split-transaction/{transaction_id}/:
    post:
      operationId: split_transaction
      description: "\n        Split a single bank transaction into multiple categorized\
        \ transactions for a specific business.\n\n        Authentication:\n     \
        \   - Requires business-scoped Bearer token (ScopedBusinessTokenAuthentication)\n\
        \        - Token business_id must match the business_id in the path\n\n  \
        \      This endpoint allows partners to split a transaction when it represents\n\
        \        multiple different expense categories that need separate tracking.\n\
        \n        **Business Rules:**\n        - Transaction must not be already approved/finalized\n\
        \        - Transaction must belong to partner's active business\n        -\
        \ Split amounts must sum to original transaction amount\n        - Each split\
        \ gets its own categorization\n        - Original transaction becomes parent\
        \ reference\n\n        **Split Behavior:**\n        - Creates child transactions\
        \ for each split\n        - Original transaction marked as parent\n      \
        \  - Each child has independent categorization\n        - Maintains full audit\
        \ trail\n        - Split transactions can be individually approved\n\n   \
        \     **Use Cases:**\n        - Mixed business/personal expenses\n       \
        \ - Multi-category purchases\n        - Shared vendor transactions\n     \
        \   - Complex expense allocation\n        "
      summary: Split Transaction (Business-scoped)
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: transaction_id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bank Transactions Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SplitTransactionRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/SplitTransactionRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/SplitTransactionRequestRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SplitTransactionResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/tasks/:
    get:
      operationId: list_tasks
      description: List all tasks for a business with filtering and search
      summary: List tasks
      parameters:
      - in: query
        name: accounting_period
        schema:
          type: string
          format: uuid
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: created_after
        schema:
          type: string
          format: date-time
      - in: query
        name: created_before
        schema:
          type: string
          format: date-time
      - in: query
        name: created_by
        schema:
          type: string
          format: uuid
      - in: query
        name: due_date_after
        schema:
          type: string
          format: date
      - in: query
        name: due_date_before
        schema:
          type: string
          format: date
      - in: query
        name: month
        schema:
          type: integer
      - name: ordering
        required: false
        in: query
        description: Which field to use when ordering the results.
        schema:
          type: string
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - name: search
        required: false
        in: query
        description: A search term.
        schema:
          type: string
      - in: query
        name: status
        schema:
          type: array
          items:
            type: string
            x-spec-enum-id: ea18c01c61dd6cc1
            enum:
            - closed
            - in_review
            - pending_response
        description: |-
          * `pending_response` - Pending Response
          * `in_review` - In Review
          * `closed` - Closed
        explode: true
        style: form
      - in: query
        name: year
        schema:
          type: integer
      tags:
      - Task Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedTaskList'
          description: ''
    post:
      operationId: create_task
      description: Create a new task with first question (atomic creation)
      summary: Create task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Task Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskCreateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TaskCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/TaskCreateRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskCreate'
          description: ''
  /v1/platform/businesses/{business_id}/tasks/{task_id}/:
    get:
      operationId: get_task
      description: Get task details including rejection reason if rejected
      summary: Get task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this task.
        required: true
      tags:
      - Task Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
          description: ''
    put:
      operationId: update_task
      description: Update task fields
      summary: Update task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this task.
        required: true
      tags:
      - Task Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TaskRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/TaskRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
          description: ''
    patch:
      operationId: partial_update_task
      description: Partially update task fields
      summary: Partially update task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this task.
        required: true
      tags:
      - Task Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedTaskRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedTaskRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedTaskRequest'
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
          description: ''
    delete:
      operationId: delete_task
      description: Delete a task
      summary: Delete task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this task.
        required: true
      tags:
      - Task Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
  /v1/platform/businesses/{business_id}/tasks/{task_id}/close/:
    post:
      operationId: close_task
      description: Mark task as closed/approved. Only bookkeeper can perform this
        action.
      summary: Close task
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this task.
        required: true
      tags:
      - Task Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
          description: ''
  /v1/platform/businesses/{business_id}/tasks/{task_id}/messages/:
    get:
      operationId: list_task_messages
      description: Get messages for a task.
      summary: Get current submission
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Task Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TaskMessage'
          description: ''
    post:
      operationId: create_task_message
      description: Submit a response to a task with optional multiple document attachments.
        Supports uploading multiple files in a single request via the 'documents'
        field. Auto-transitions task status to 'in_review'.
      summary: Submit response
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Task Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskMessageCreateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TaskMessageCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/TaskMessageCreateRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskMessageCreate'
          description: ''
  /v1/platform/businesses/{business_id}/tasks/{task_id}/messages/{message_id}/:
    get:
      operationId: get_task_message
      description: Get message details with document download URLs
      summary: Get message details
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: message_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this task message.
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Task Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskMessage'
          description: ''
    patch:
      operationId: update_task_message
      description: Update a message with optional multiple document attachments. Supports
        uploading multiple files in a single request via the 'documents' field.
      summary: Update message
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: message_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this task message.
        required: true
      - in: path
        name: task_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Task Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedTaskMessageUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedTaskMessageUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedTaskMessageUpdateRequest'
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskMessageUpdate'
          description: ''
  /v1/platform/businesses/{business_id}/tasks/period_overview/:
    get:
      operationId: period_overview
      description: Returns task counts for each accounting period in the fiscal year.
        Use this to show dashboard cards with pending document counts.
      summary: Get pending task counts per month
      parameters:
      - in: query
        name: accounting_period
        schema:
          type: string
          format: uuid
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: created_after
        schema:
          type: string
          format: date-time
      - in: query
        name: created_before
        schema:
          type: string
          format: date-time
      - in: query
        name: created_by
        schema:
          type: string
          format: uuid
      - in: query
        name: due_date_after
        schema:
          type: string
          format: date
      - in: query
        name: due_date_before
        schema:
          type: string
          format: date
      - in: query
        name: month
        schema:
          type: integer
      - name: ordering
        required: false
        in: query
        description: Which field to use when ordering the results.
        schema:
          type: string
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - name: search
        required: false
        in: query
        description: A search term.
        schema:
          type: string
      - in: query
        name: status
        schema:
          type: array
          items:
            type: string
            x-spec-enum-id: ea18c01c61dd6cc1
            enum:
            - closed
            - in_review
            - pending_response
        description: |-
          * `pending_response` - Pending Response
          * `in_review` - In Review
          * `closed` - Closed
        explode: true
        style: form
      - in: query
        name: year
        schema:
          type: integer
      tags:
      - Task Management
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedPeriodOverviewItemList'
          description: ''
  /v1/platform/businesses/{business_id}/unarchive/:
    post:
      operationId: unarchive_business
      description: Unarchive a business
      summary: Unarchive business
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this business.
        required: true
      tags:
      - Business Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BusinessRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/BusinessRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/BusinessRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Business'
              examples:
                UKLimitedCompany:
                  value:
                    id: 3c90c3cc-0d44-4b50-8888-8dd25736052a
                    external_id: customer-123
                    legal_name: Acme Coffee Limited
                    name: Acme Coffee Ltd
                    entity_type: limited
                    phone_number: +44 20 1234 5678
                    tin: '1234567890'
                    vat_number: GB123456789
                    company_number: '12345678'
                    country: GB
                    province: Greater London
                    eu_nace_industry_code: '56.30'
                    email: accounting@acmecoffee.co.uk
                    base_currency: GBP
                    accounting_method: accrual
                    fiscal_year_end: '2024-03-31'
                    activation_at: '2024-01-15T10:30:00Z'
                    is_active: true
                    created_at: '2024-01-15T10:30:00Z'
                    updated_at: '2024-03-20T14:22:00Z'
                    metadata:
                      erp_id: ERP-12345
                      industry: hospitality
                  summary: UK Limited Company
          description: ''
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/uncategorize-transaction/{transaction_id}/:
    post:
      operationId: uncategorize_transaction
      description: "\n        Uncategorize an approved transaction to allow re-categorization.\n\
        \n        **Authentication:**\n        - Requires business-scoped Bearer token\
        \ (ScopedBusinessTokenAuthentication)\n        - Token business_id must match\
        \ the business_id in the path\n\n        **Two-Status Model:**\n        This\
        \ endpoint resets both status fields:\n        - `categorization_status`:\
        \ Reset to `pending`\n        - `approval_status`: Reset to `pending_approval`\n\
        \n        **Prerequisites:**\n        - Transaction must be approved (`approval_status`\
        \ = `ai_approved` or `approved`)\n        - Cannot uncategorize transactions\
        \ that are already pending\n\n        **What This Endpoint Does:**\n     \
        \   - Resets `categorization_status` to `pending`\n        - Resets `approval_status`\
        \ to `pending_approval`\n        - Clears subcategory assignment\n       \
        \ - Creates audit trail\n\n        **Workflow to Change Category on Approved\
        \ Transaction:**\n        1. Call this endpoint to uncategorize\n        2.\
        \ Call `PATCH /update-transaction-categorization/` with new subcategory_id\n\
        \n        **Future Behavior (when ledger is implemented):**\n        - Creates\
        \ reversing journal entry\n        - Posts reversal to ledger\n        - Validates\
        \ accounting period allows changes\n\n        **Response includes:**\n   \
        \     - `categorization_status`: \"pending\"\n        - `approval_status`:\
        \ \"pending_approval\"\n        - `uncategorized_at`: timestamp\n        -\
        \ `uncategorized_by`: user/partner name\n        "
      summary: Uncategorize Transaction (Business-scoped)
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: transaction_id
        schema:
          type: string
        required: true
      tags:
      - Bank Transactions Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UnCategorizeTransactionResponseRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UnCategorizeTransactionResponseRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UnCategorizeTransactionResponseRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnCategorizeTransactionResponse'
              examples:
                UncategorizeApprovedTransaction:
                  summary: Uncategorize Approved Transaction
                  description: Reset an approved transaction to pending state for
                    re-categorization
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/update-transaction-categorization/{transaction_id}/:
    patch:
      operationId: update_transaction_categorization
      description: "\n        Categorize and approve a bank transaction for a specific\
        \ business.\n\n        **Authentication:**\n        - Requires business-scoped\
        \ Bearer token (ScopedBusinessTokenAuthentication)\n        - Token business_id\
        \ must match the business_id in the path\n\n        **Two-Status Model:**\n\
        \        This API uses a two-field status model:\n        - `categorization_status`:\
        \ Whether category is set (pending, categorized, manual_review, approved)\n\
        \        - `approval_status`: Whether approved for posting (pending_approval,\
        \ ai_approved, approved)\n\n        **What This Endpoint Does:**\n       \
        \ - Sets `categorization_status` to `categorized`\n        - Sets `approval_status`\
        \ to `approved`\n        - Triggers Journal Entry creation (when approved)\n\
        \n        **Prerequisites:**\n        - Transaction must have `approval_status\
        \ = pending_approval`\n        - Cannot modify already approved transactions\
        \ (ai_approved or approved)\n        - To change category on approved transaction:\
        \ call uncategorize first, then re-categorize\n\n        **Request Body:**\n\
        \        ```json\n        {\n          \"subcategory_id\": \"uuid-of-subcategory\"\
        ,\n          \"description_override\": \"optional description\",\n       \
        \   \"counterparty_name_override\": \"optional counterparty name\"\n     \
        \   }\n        ```\n\n        **Response includes:**\n        - `categorization_status`:\
        \ \"categorized\"\n        - `approval_status`: \"approved\"\n        - `requires_approval`:\
        \ false\n        - `category` and `subcategory` details\n\n        **Use Cases:**\n\
        \        - Approving AI-suggested categorizations\n        - Correcting and\
        \ approving miscategorized transactions\n        - Manual categorization of\
        \ uncategorized transactions\n        "
      summary: Categorize & Approve Transaction (Business-scoped)
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        required: true
      - in: path
        name: transaction_id
        schema:
          type: string
        required: true
      tags:
      - Bank Transactions Management
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedTransactionCategorizationRequestRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedTransactionCategorizationRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedTransactionCategorizationRequestRequest'
      security:
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionCategorizationResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/vendor-credits/:
    get:
      operationId: list_vendor_credits
      description: List all vendor credits for a business with optional filtering
        and pagination. Supports filtering by status, vendor, and date ranges.
      summary: List Vendor Credits
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      - in: query
        name: received_at_end
        schema:
          type: string
        description: Filter credits received at or before this ISO timestamp
        examples:
          EndDate:
            value: '2024-12-31T23:59:59Z'
            summary: End Date
      - in: query
        name: received_at_start
        schema:
          type: string
        description: Filter credits received at or after this ISO timestamp
        examples:
          StartDate:
            value: '2024-01-01T00:00:00Z'
            summary: Start Date
      - in: query
        name: search
        schema:
          type: string
        description: Search in credit note number, external ID, and vendor name
      - in: query
        name: source_bill_id
        schema:
          type: string
          format: uuid
        description: Filter by source bill ID (origin tracking)
      - in: query
        name: status
        schema:
          type: string
        description: Comma-separated statuses (draft,received,applied,partially_applied,void)
        examples:
          SingleStatus:
            value: received
            summary: Single Status
          MultipleStatuses:
            value: received,applied
            summary: Multiple Statuses
      - in: query
        name: vendor_external_id
        schema:
          type: string
        description: Filter by vendor external id
        examples:
          ExternalVendorID:
            value: vendor-001
            summary: External Vendor ID
      - in: query
        name: vendor_id
        schema:
          type: string
        description: Filter by vendor ID (supports comma-separated UUIDs for multiple
          vendors)
        examples:
          VendorID:
            value: 456e7890-e12b-34c5-d678-901234567890
            summary: Vendor ID
      tags:
      - Vendor Credits
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedVendorCreditList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    post:
      operationId: create_vendor_credit
      description: Create a vendor credit note with line items and optional allocations.
        Supports idempotency via external_id and can create vendors on-the-fly using
        vendor_external_id.
      summary: Create Vendor Credit
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Vendor Credits
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateVendorCreditRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateVendorCreditRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateVendorCreditRequest'
        required: true
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorCredit'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/vendor-credits/{credit_id}/:
    get:
      operationId: get_vendor_credit
      description: Fetch a single vendor credit by ID. Returns complete credit details
        including line items, allocations, and metadata.
      summary: Get Vendor Credit
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: credit_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor credit note.
        required: true
      tags:
      - Vendor Credits
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorCredit'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    put:
      operationId: update_vendor_credit
      description: Update vendor credit.
      summary: Update Vendor Credit
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: credit_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor credit note.
        required: true
      tags:
      - Vendor Credits
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateVendorCreditRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UpdateVendorCreditRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UpdateVendorCreditRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorCredit'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
    delete:
      operationId: delete_vendor_credit
      description: Soft delete vendor credit.
      summary: Delete (soft) Vendor Credit
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: credit_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor credit note.
        required: true
      tags:
      - Vendor Credits
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/vendor-refunds/:
    get:
      operationId: list_vendor_refunds
      description: "\n        List all vendor refunds for a business with advanced\
        \ filtering and search.\n\n        **Features:**\n        - Filter by status,\
        \ refund type, vendor, date range, amount\n        - Full-text search across\
        \ reference numbers and descriptions\n        - Sort by any field\n      \
        \  - Pagination support\n\n        **Use Cases:**\n        - View all pending\
        \ refunds requiring processing\n        - Find refunds for a specific vendor\n\
        \        - Track refund history for accounting reconciliation\n        - Monitor\
        \ unallocated refunds\n\n        **Available Filters:**\n        - `status`:\
        \ Filter by refund status (pending, partially_allocated, allocated, completed,\
        \ cancelled).\n          Comma-separated for multiple.\n        - `refund_type`:\
        \ Filter by type (overpayment, credit_balance, billing_error, etc.)\n    \
        \    - `vendor_id`: Filter by specific vendor UUID\n        - `refund_date_start`\
        \ / `refund_date_end`: Filter by date range (YYYY-MM-DD)\n        - `min_amount`\
        \ / `max_amount`: Filter by amount range (in cents)\n        - `currency`:\
        \ Filter by currency code (EUR, GBP, USD)\n        - `is_fully_allocated`:\
        \ Filter by allocation status (true/false)\n        - `search`: Full-text\
        \ search across reference_number, external_id, description, vendor name\n\n\
        \        **Ordering:**\n        - Default: `-refund_date,-created_at` (newest\
        \ first)\n        - Options: `refund_date`, `total_refunded_amount_cents`,\
        \ `status`, `vendor__company_name`\n        - Prefix with `-` for descending\
        \ order\n        "
      summary: List vendor refunds
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: currency
        schema:
          type: string
        description: Filter by currency code (EUR, GBP, USD)
      - in: query
        name: external_id
        schema:
          type: string
        description: Filter by external ID (partial match)
      - in: query
        name: is_fully_allocated
        schema:
          type: boolean
        description: Filter by allocation status (true=fully allocated, false=has
          unallocated amount)
      - in: query
        name: max_amount
        schema:
          type: integer
        description: Maximum refund amount in cents
      - in: query
        name: min_amount
        schema:
          type: integer
        description: Minimum refund amount in cents
      - in: query
        name: ordering
        schema:
          type: string
        description: Order results by field (prefix with - for descending)
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - in: query
        name: reference_number
        schema:
          type: string
        description: Filter by reference number (partial match)
      - in: query
        name: refund_date_end
        schema:
          type: string
          format: date
        description: Filter refunds to this date (YYYY-MM-DD)
      - in: query
        name: refund_date_start
        schema:
          type: string
          format: date
        description: Filter refunds from this date (YYYY-MM-DD)
      - in: query
        name: refund_type
        schema:
          type: string
          x-spec-enum-id: 9e7c4f2adc5c33a3
          enum:
          - billing_error
          - credit_balance
          - duplicate_payment
          - goods_return
          - other
          - overpayment
          - service_cancellation
        description: |-
          Filter by refund type

          * `overpayment` - Overpayment Refund
          * `credit_balance` - Credit Balance Refund
          * `duplicate_payment` - Duplicate Payment
          * `billing_error` - Billing Error
          * `goods_return` - Goods Return
          * `service_cancellation` - Service Cancellation
          * `other` - Other
      - in: query
        name: search
        schema:
          type: string
        description: Search across reference_number, external_id, description, vendor
          name
      - in: query
        name: status
        schema:
          type: string
        description: Filter by refund status (comma-separated for multiple)
      - in: query
        name: vendor_external_id
        schema:
          type: string
        description: Filter by vendor external ID
      - in: query
        name: vendor_id
        schema:
          type: string
        description: Filter by vendor ID (supports comma-separated UUIDs for multiple
          vendors)
      tags:
      - Vendor Refunds
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedVendorRefundList'
          description: ''
      x-audience:
      - partner
    post:
      operationId: create_vendor_refund
      description: "\n        Create a new vendor refund record (parent transaction).\n\
        \n        **Idempotency**: Uses `external_id` field - duplicate requests with\
        \ the same\n        `external_id` will return HTTP 200 with the existing refund\
        \ instead of creating\n        a duplicate.\n\n        **Required Fields:**\n\
        \        - `vendor_id`: UUID of the vendor issuing the refund\n        - `total_refunded_amount_cents`:\
        \ Total amount being refunded in cents (e.g., 10050 for £100.50)\n       \
        \ - `currency`: ISO 4217 currency code (EUR, GBP, USD)\n\n        **Optional\
        \ Fields:**\n        - `external_id`: Your system's unique identifier (for\
        \ idempotency)\n        - `reference_number`: External reference number\n\
        \        - `refund_type`: Type of refund (overpayment, billing_error, goods_return,\
        \ etc.)\n        - `refund_date`: Date of refund (defaults to today)\n   \
        \     - `description`: Detailed description\n        - `memo`: Internal memo/notes\n\
        \        - `reason`: Reason for the refund\n        - `metadata`: Additional\
        \ structured data (JSON object)\n        - `allocations`: Array of allocations\
        \ to create with the refund\n        - `payments`: Array of payments to create\
        \ with the refund\n        - `document`: Optional document upload (multipart\
        \ field `file` with optional document_type, upload_source, metadata, tags)\n\
        \n        **Common Scenarios:**\n        1. **Overpayment refund** - Vendor\
        \ returns excess payment\n           ```json\n           {\n             \"\
        vendor_id\": \"uuid\",\n             \"total_refunded_amount_cents\": 15000,\n\
        \             \"currency\": \"GBP\",\n             \"refund_type\": \"overpayment\"\
        ,\n             \"description\": \"Refund of overpayment\"\n           }\n\
        \           ```\n\n        2. **Billing error** - Vendor refunds due to billing\
        \ mistake\n           ```json\n           {\n             \"vendor_id\": \"\
        uuid\",\n             \"total_refunded_amount_cents\": 50000,\n          \
        \   \"currency\": \"GBP\",\n             \"refund_type\": \"billing_error\"\
        ,\n             \"reference_number\": \"REF-12345\",\n             \"allocations\"\
        : [{\n               \"allocation_type\": \"bill\",\n               \"bill_id\"\
        : \"bill-uuid\",\n               \"amount_cents\": 50000\n             }]\n\
        \           }\n           ```\n\n        3. **Complete refund with payment**\
        \ - Create refund with allocation and payment in one request\n           ```json\n\
        \           {\n             \"vendor_id\": \"uuid\",\n             \"total_refunded_amount_cents\"\
        : 100000,\n             \"currency\": \"GBP\",\n             \"external_id\"\
        : \"my-refund-123\",\n             \"allocations\": [{\n               \"\
        allocation_type\": \"bill\",\n               \"bill_id\": \"bill-uuid\",\n\
        \               \"amount_cents\": 100000\n             }],\n             \"\
        payments\": [{\n               \"refunded_amount_cents\": 100000,\n      \
        \         \"payment_method\": \"bank_transfer\",\n               \"processor\"\
        : \"wise\"\n             }]\n           }\n           ```\n\n        **Returns:**\n\
        \        - HTTP 201: Refund created successfully\n        - HTTP 200: Existing\
        \ refund (idempotent - same external_id)\n        - HTTP 400: Validation error\n\
        \        "
      summary: Create vendor refund
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Vendor Refunds
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateVendorRefundRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateVendorRefundRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateVendorRefundRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorRefund'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/vendor-refunds/{refund_id}/:
    get:
      operationId: get_vendor_refund
      description: "\n        Retrieve complete details of a specific vendor refund\
        \ including\n        all allocations and payments.\n        "
      summary: Get vendor refund details
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor refund.
        required: true
      tags:
      - Vendor Refunds
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorRefund'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    patch:
      operationId: update_vendor_refund
      description: Update vendor refund fields (description, memo, metadata, etc.).
        Supports optional document upload via multipart field `document` (with optional
        document_type, upload_source, metadata, tags). JSON-only requests remain supported
        when no file is provided.
      summary: Update vendor refund
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor refund.
        required: true
      tags:
      - Vendor Refunds
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedVendorRefundUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedVendorRefundUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedVendorRefundUpdateRequest'
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorRefund'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    delete:
      operationId: delete_vendor_refund
      description: Soft-delete a vendor refund (sets deleted_at timestamp)
      summary: Delete vendor refund
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor refund.
        required: true
      tags:
      - Vendor Refunds
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/vendor-refunds/{refund_id}/allocations/{allocation_id}/:
    delete:
      operationId: delete_vendor_refund_allocation
      description: Unlink a bill from the vendor refund by deleting the allocation.
      summary: Delete vendor refund allocation
      parameters:
      - in: path
        name: allocation_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: refund_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor refund.
        required: true
      tags:
      - Vendor Refunds
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '204':
          description: No response body
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
  /v1/platform/businesses/{business_id}/vendor-refunds/payments/:
    get:
      operationId: list_vendor_refund_payments
      description: "\n        List all vendor refund payments for a business with\
        \ filtering and pagination.\n\n        **Features:**\n        - Filter by\
        \ status (pending, processing, completed, failed, cancelled)\n        - Filter\
        \ by payment method\n        - Filter by date range\n        - Search by payment\
        \ reference\n        - Pagination support (default: 20 per page, max: 100)\n\
        \n        **Use Cases:**\n        - View all pending payments requiring processing\n\
        \        - Monitor payment status across all refunds\n        - Generate payment\
        \ reports\n        - Reconciliation dashboard\n\n        **Available Filters:**\n\
        \        - `status`: Filter by payment status\n        - `payment_method`:\
        \ Filter by payment method (bank_transfer, check, etc.)\n        - `refund_id`:\
        \ Filter by specific vendor refund UUID\n        - `payment_date_start` /\
        \ `payment_date_end`: Filter by date range\n        - `search`: Search by\
        \ payment_reference\n        "
      summary: List vendor refund payments
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - in: query
        name: payment_date_end
        schema:
          type: string
          format: date
        description: Filter payments to this date (YYYY-MM-DD)
      - in: query
        name: payment_date_start
        schema:
          type: string
          format: date
        description: Filter payments from this date (YYYY-MM-DD)
      - in: query
        name: payment_method
        schema:
          type: string
        description: Filter by payment method
      - in: query
        name: refund_id
        schema:
          type: string
          format: uuid
        description: Filter by vendor refund UUID
      - in: query
        name: search
        schema:
          type: string
        description: Search by payment reference
      - in: query
        name: status
        schema:
          type: string
        description: Filter by payment status
      tags:
      - Vendor Refund Payments
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedVendorRefundPaymentListList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: create_vendor_refund_payment_allocation
      description: "\n        Create a vendor refund payment with embedded allocations\
        \ in a single atomic operation.\n\n        This endpoint follows the same\
        \ pattern as invoice payments, where allocations\n        are embedded in\
        \ the payment creation request rather than being separate API calls.\n\n \
        \       **Key Features:**\n        - Atomic operation - all or nothing\n \
        \       - Comprehensive validation\n        - Support for multiple allocation\
        \ types\n        - Idempotency support via `Idempotency-Key` header\n\n  \
        \      **Allocation Types:**\n        - `bill`: Apply refund to a specific\
        \ bill\n        - `payment`: Refund a specific bill payment\n        - `credit`:\
        \ Create a credit balance for future use\n\n        **Idempotency:**\n   \
        \     Include an `Idempotency-Key` header to ensure the same request isn't\
        \ processed twice.\n        If the same key is used again, the original response\
        \ will be returned.\n\n        **Example Request:**\n        ```json\n   \
        \     {\n          \"vendor_id\": \"uuid\",\n          \"total_amount_cents\"\
        : 100000,\n          \"payment_method\": \"bank_transfer\",\n          \"\
        refund_date\": \"2025-01-15\",\n          \"allocations\": [\n           \
        \ {\n              \"allocation_type\": \"bill\",\n              \"bill_id\"\
        : \"uuid\",\n              \"amount_cents\": 60000,\n              \"description\"\
        : \"Partial refund for Bill #123\"\n            },\n            {\n      \
        \        \"allocation_type\": \"credit\",\n              \"amount_cents\"\
        : 40000,\n              \"description\": \"Credit for future purchases\"\n\
        \            }\n          ]\n        }\n        ```\n        "
      summary: Create vendor refund payment with allocations
      parameters:
      - in: header
        name: Idempotency-Key
        schema:
          type: string
        description: Unique key for idempotent request processing
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      tags:
      - Vendor Refund Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VendorRefundPaymentCreateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/VendorRefundPaymentCreateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/VendorRefundPaymentCreateRequest'
        required: true
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorRefundPaymentCreateResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/vendor-refunds/payments/{vendor_refund_payment_id}/:
    get:
      operationId: get_vendor_refund_payment
      description: "\n        Retrieve detailed information about a specific vendor\
        \ refund payment.\n\n        **Returns:**\n        - Complete payment information\n\
        \        - Associated refund details\n        - Vendor information\n     \
        \   - Allocations (bills, bill payments, credits)\n        - Reconciliation\
        \ status\n\n        **Use Cases:**\n        - View payment status and details\n\
        \        - Check allocation breakdown\n        - Audit trail\n        - Debugging\
        \ and support\n        "
      summary: Get vendor refund payment details
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: path
        name: vendor_refund_payment_id
        schema:
          type: string
          format: uuid
        description: Vendor Refund Payment UUID
        required: true
      tags:
      - Vendor Refund Payments
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorRefundPaymentCreateResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    patch:
      operationId: update_vendor_refund_payment
      description: "\n        Update an existing vendor refund payment's status or\
        \ details.\n\n        **Updatable Fields:**\n        - `status`: Update payment\
        \ status (with validation)\n        - `failure_reason`: Required when status\
        \ is 'failed'\n        - `payment_reference`: Update external reference\n\
        \        - `processing_fee_cents`: Update processing fee\n\n        **Status\
        \ Transitions:**\n        - `pending` → `processing`, `completed`, `failed`,\
        \ `cancelled`\n        - `processing` → `completed`, `failed`\n        - `completed`\
        \ → (no transitions allowed)\n        - `failed` → (no transitions allowed)\n\
        \        - `cancelled` → (no transitions allowed)\n        "
      summary: Update vendor refund payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: path
        name: vendor_refund_payment_id
        schema:
          type: string
          format: uuid
        description: Vendor Refund Payment UUID
        required: true
      tags:
      - Vendor Refund Payments
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedVendorRefundPaymentUpdateRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PatchedVendorRefundPaymentUpdateRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/PatchedVendorRefundPaymentUpdateRequest'
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorRefundPaymentCreateResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/vendor-refunds/payments/{vendor_refund_payment_id}/delete/:
    post:
      operationId: delete_vendor_refund_payment
      description: Cancel a vendor refund payment and reverse its allocations. Only
        pending or failed payments can be deleted. Completed payments cannot be deleted.
        This operation marks the payment as cancelled and updates bill/refund statuses.
        Following the REST pattern, this uses POST method as it's a state change operation,
        not a resource deletion.
      summary: Delete (cancel) vendor refund payment
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID
        required: true
      - in: path
        name: vendor_refund_payment_id
        schema:
          type: string
          format: uuid
        description: Vendor Refund Payment UUID
        required: true
      tags:
      - Vendor Refund Payments
      security:
      - BusinessScopedJWT: []
      - PartnerJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorRefundPaymentCancelResponse'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/vendors/:
    get:
      operationId: list_vendors
      description: List all vendors within a business. Active vendors are returned
        by default; include archived ones with include_archived=true.
      summary: List vendors
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: query
        name: external_id
        schema:
          type: string
        description: The external ID of the vendor to fetch (exact match).
      - in: query
        name: external_id_contains
        schema:
          type: string
        description: Filter vendors whose external ID contains the given substring
          (case-insensitive).
      - in: query
        name: include_archived
        schema:
          type: boolean
          default: false
        description: Include archived vendors in the response. Defaults to false.
      - in: query
        name: name
        schema:
          type: string
        description: Exact name match on company or individual name.
      - in: query
        name: name_contains
        schema:
          type: string
        description: Substring match on company or individual name (case-insensitive).
      - in: query
        name: page
        schema:
          type: integer
        description: 'Page number (default: 1)'
      - in: query
        name: page_size
        schema:
          type: integer
        description: 'Items per page (default: 20, max: 100)'
      tags:
      - Vendors
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedVendorList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    post:
      operationId: create_vendor
      description: Create a new vendor within a business.
      summary: Create vendor
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      tags:
      - Vendors
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateVendorRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateVendorRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateVendorRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vendor'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/vendors/{vendor_id}/:
    get:
      operationId: fetch_vendor
      description: Fetch a single vendor by ID for the specified business.
      summary: Fetch vendor
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: vendor_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor.
        required: true
      tags:
      - Vendors
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vendor'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
    put:
      operationId: update_vendor
      description: Update an existing vendor
      summary: Update vendor
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: vendor_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor.
        required: true
      tags:
      - Vendors
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateVendorRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/UpdateVendorRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UpdateVendorRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vendor'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/vendors/{vendor_id}/archive/:
    post:
      operationId: archive_vendor
      description: Archive a vendor (soft-delete semantics)
      summary: Archive vendor
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: vendor_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor.
        required: true
      tags:
      - Vendors
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VendorRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/VendorRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/VendorRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vendor'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/businesses/{business_id}/vendors/{vendor_id}/unarchive/:
    post:
      operationId: unarchive_vendor
      description: Reactivate a previously archived vendor
      summary: Unarchive vendor
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          pattern: ^[0-9a-f-]+$
        required: true
      - in: path
        name: vendor_id
        schema:
          type: string
          format: uuid
        description: A UUID string identifying this vendor.
        required: true
      tags:
      - Vendors
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VendorRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/VendorRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/VendorRequest'
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vendor'
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
      x-audience:
      - partner
  /v1/platform/oauth2/token/:
    post:
      operationId: get_partner_token
      description: OAuth2 token endpoint using Basic Authentication. Provide partner_uuid:api_key
        as username:password in Basic Auth header. Request body should be form-encoded
        with grant_type=client_credentials.
      summary: Get partner access token (client credentials)
      tags:
      - Oauth2 authentication - Unscoped and Scoped
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OAuth2TokenRequestRequest'
            examples:
              GetPartnerToken:
                value:
                  grant_type: client_credentials
                  client_id: a1b2c3d4-5678-90ab-cdef-1234567890ab
                summary: Get Partner Token
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/OAuth2TokenRequestRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/OAuth2TokenRequestRequest'
        required: true
      security:
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2TokenResponse'
              examples:
                PartnerTokenResponse:
                  value:
                    access_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhMWIyYzNkNC01Njc4LTkwYWItY2RlZi0xMjM0NTY3ODkwYWIiLCJpYXQiOjE3MDk4MjEyMDAsImV4cCI6MTcwOTgyNDgwMH0.example
                    token_type: Bearer
                    expires_in: 3600
                  summary: Partner Token Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2ErrorResponse'
          description: ''
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2ErrorResponse'
          description: ''
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuth2ErrorResponse'
          description: ''
      x-audience:
      - partner
  /v1/platform/transaction-categories/{business_id}:
    get:
      operationId: list_transaction_categories
      description: "\n        Retrieve all active transaction categories with their\
        \ subcategories.\n\n        This endpoint returns a hierarchical structure\
        \ of categories and subcategories\n        that can be used to build two-level\
        \ category selectors in the UI.\n\n        **Use Cases:**\n        - Build\
        \ category dropdown menus (Category → Subcategory)\n        - Display category\
        \ hierarchy for transaction categorization\n        - Get available categories\
        \ for a specific business\n\n        **Response Structure:**\n        - Returns\
        \ all active categories ordered by name\n        - Each category includes\
        \ its active subcategories\n        - Subcategories include full_code for\
        \ backward compatibility\n\n        **Business Access:**\n        - Requires\
        \ valid business_id that partner has access to\n        - Categories are global\
        \ but scoped by business access\n        "
      summary: List Transaction Categories
      parameters:
      - in: path
        name: business_id
        schema:
          type: string
          format: uuid
        description: Business UUID to verify partner access
        required: true
      tags:
      - Bank Transactions Management
      security:
      - PartnerJWT: []
      - BusinessScopedJWT: []
      - BasicAuth: []
      - BearerUnscoped: []
      - BearerBusinessScoped: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CategoryListResponse'
              examples:
                SuccessResponse:
                  value:
                    count: 29
                    results:
                    - id: 550e8400-e29b-41d4-a716-446655440000
                      code: travel_and_transport
                      name: Travel & Transport
                      description: Business travel, accommodation, and transport expenses
                      subcategories:
                      - id: 650e8400-e29b-41d4-a716-446655440001
                        code: local_transport
                        name: Local transport
                        description: ''
                        full_code: travel_and_transport.local_transport
                        is_active: true
                      - id: 650e8400-e29b-41d4-a716-446655440002
                        code: accommodation
                        name: Accommodation
                        description: ''
                        full_code: travel_and_transport.accommodation
                        is_active: true
                      subcategory_count: 5
                      is_active: true
                  summary: Success Response
          description: ''
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
          description: Validation errors in request data
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Authentication required - missing or invalid API key
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Permission denied - insufficient privileges
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Resource not found
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Conflict - resource already exists or invalid state transition
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Unprocessable entity - business logic validation failed
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal server error
components:
  schemas:
    APAging:
      type: object
      description: |-
        Complete AP aging response.

        Includes:
        - Business and date metadata
        - Total outstanding across all vendors
        - Total aging buckets (sum across all vendors)
        - Per-vendor breakdown (sorted by total outstanding descending)
      properties:
        business_id:
          type: string
          format: uuid
          description: Business UUID
        as_of_date:
          type: string
          format: date
          description: Date to calculate aging as of
        group_by:
          enum:
          - vendor
          - total
          type: string
          x-spec-enum-id: b6fb7084481de76a
          description: |-
            Grouping: 'vendor' or 'total'

            * `vendor` - vendor
            * `total` - total
        currency:
          type: string
          description: Business base currency (e.g., EUR, GBP, USD)
        total_outstanding_cents:
          type: integer
          description: Total outstanding across all vendors in cents
        total_aging_buckets:
          allOf:
          - $ref: '#/components/schemas/APAgingBuckets'
          description: Total aging buckets (sum across all vendors)
        vendors:
          type: array
          items:
            $ref: '#/components/schemas/VendorAging'
          description: Per-vendor aging breakdown (sorted by total outstanding descending)
      required:
      - as_of_date
      - business_id
      - currency
      - group_by
      - total_aging_buckets
      - total_outstanding_cents
      - vendors
    APAgingBuckets:
      type: object
      description: |-
        Aging buckets for outstanding amounts.

        Buckets:
        - current: Due today or in the future (0 days overdue or negative)
        - 1_30_days: 1-30 days overdue
        - 31_60_days: 31-60 days overdue
        - 61_90_days: 61-90 days overdue
        - over_90_days: 90+ days overdue

        All amounts in cents.
      properties:
        current:
          type: integer
          description: Amount not yet due (0 days overdue) in cents
        days_1_30:
          type: integer
          description: Amount 1-30 days overdue in cents
        days_31_60:
          type: integer
          description: Amount 31-60 days overdue in cents
        days_61_90:
          type: integer
          description: Amount 61-90 days overdue in cents
        over_90_days:
          type: integer
          description: Amount 90+ days overdue in cents
      required:
      - current
      - days_1_30
      - days_31_60
      - days_61_90
      - over_90_days
    APDocumentUploadRequestRequest:
      type: object
      description: Request serializer for AP document upload endpoint
      properties:
        file:
          type: string
          format: binary
          description: PDF or image file to upload (max 50MB)
      required:
      - file
    APDocumentUploadResponse:
      type: object
      description: Response serializer for AP document upload endpoint
      properties:
        document_id:
          type: string
          format: uuid
          description: Unique identifier for the uploaded document
        task_id:
          type: string
          description: Celery task ID for tracking processing
        status:
          type: string
          description: Current status (always 'processing' initially)
        message:
          type: string
          description: Instructions for checking result
      required:
      - document_id
      - message
      - status
      - task_id
    APStats:
      type: object
      description: |-
        Accounts Payable statistics aggregating all AP entity counts.

        Returns nested counts for:
        - Bills (purchase invoices)
        - Vendor Credits
        - Vendor Refunds
        - Receipts (with payment method breakdown)
      properties:
        bills:
          allOf:
          - $ref: '#/components/schemas/BillStats'
          description: Bill statistics
        vendor_credits:
          allOf:
          - $ref: '#/components/schemas/VendorCreditStats'
          description: Vendor credit statistics
        vendor_refunds:
          allOf:
          - $ref: '#/components/schemas/VendorRefundStats'
          description: Vendor refund statistics
        receipts:
          allOf:
          - $ref: '#/components/schemas/ReceiptStats'
          description: Receipt statistics
      required:
      - bills
      - receipts
      - vendor_credits
      - vendor_refunds
    ARAging:
      type: object
      description: |-
        Complete AR aging response.

        Includes:
        - Business and date metadata
        - Total outstanding across all customers
        - Total aging buckets (sum across all customers)
        - Per-customer breakdown (sorted by total outstanding descending)
      properties:
        business_id:
          type: string
          format: uuid
          description: Business UUID
        as_of_date:
          type: string
          format: date
          description: Date to calculate aging as of
        group_by:
          enum:
          - customer
          - total
          type: string
          x-spec-enum-id: 1f4b3152a5bd61d9
          description: |-
            Grouping: 'customer' or 'total'

            * `customer` - customer
            * `total` - total
        currency:
          type: string
          description: Business base currency (e.g., EUR, GBP, USD)
        total_outstanding_cents:
          type: integer
          description: Total outstanding across all customers in cents
        total_aging_buckets:
          allOf:
          - $ref: '#/components/schemas/ARAgingBuckets'
          description: Total aging buckets (sum across all customers)
        customers:
          type: array
          items:
            $ref: '#/components/schemas/CustomerAging'
          description: Per-customer aging breakdown (sorted by total outstanding descending)
      required:
      - as_of_date
      - business_id
      - currency
      - customers
      - group_by
      - total_aging_buckets
      - total_outstanding_cents
    ARAgingBuckets:
      type: object
      description: |-
        Aging buckets for outstanding amounts.

        Buckets:
        - current: Due today or in the future (0 days overdue or negative)
        - 1_30_days: 1-30 days overdue
        - 31_60_days: 31-60 days overdue
        - 61_90_days: 61-90 days overdue
        - over_90_days: 90+ days overdue

        All amounts in cents.
      properties:
        current:
          type: integer
          description: Amount not yet due (0 days overdue) in cents
        days_1_30:
          type: integer
          description: Amount 1-30 days overdue in cents
        days_31_60:
          type: integer
          description: Amount 31-60 days overdue in cents
        days_61_90:
          type: integer
          description: Amount 61-90 days overdue in cents
        over_90_days:
          type: integer
          description: Amount 90+ days overdue in cents
      required:
      - current
      - days_1_30
      - days_31_60
      - days_61_90
      - over_90_days
    ARStats:
      type: object
      description: |-
        Accounts Receivable statistics aggregating all AR entity counts.

        Returns nested counts for:
        - Invoices (customer invoices)
        - Refunds (customer refunds)
        - Credit Notes (customer credit notes)
      properties:
        invoices:
          allOf:
          - $ref: '#/components/schemas/InvoiceStats'
          description: Invoice statistics
        refunds:
          allOf:
          - $ref: '#/components/schemas/RefundStats'
          description: Customer refund statistics
        credit_notes:
          allOf:
          - $ref: '#/components/schemas/CreditNoteStats'
          description: Credit note statistics
      required:
      - credit_notes
      - invoices
      - refunds
    AccountCreateAPIRequest:
      type: object
      description: |-
        Serializer for creating accounts via the Chart of Accounts API.

        Supports flexible parent identification (UUID, code, or external_id).
        Implements idempotency via external_id field.
      properties:
        code:
          type: string
          minLength: 1
          description: Unique account code within business (e.g., '1000', 'REV-SALES')
          maxLength: 50
        name:
          type: string
          description: Account display name. Maps to custom_name field.
          maxLength: 255
        account_type:
          enum:
          - asset
          - liability
          - equity
          - revenue
          - expense
          - ''
          type: string
          x-spec-enum-id: bee27527493b2230
          description: |-
            Account type: asset, liability, equity, revenue, expense

            * `asset` - Asset
            * `liability` - Liability
            * `equity` - Equity
            * `revenue` - Revenue
            * `expense` - Expense
        account_subtype:
          enum:
          - current_assets
          - non_current_assets
          - current_liabilities
          - non_current_liabilities
          - share_capital
          - share_premium
          - reserves
          - retained_earnings
          - revenue
          - other_operating_income
          - finance_income
          - direct_costs
          - operating_expenses
          - finance_costs
          - income_tax
          - ''
          type: string
          x-spec-enum-id: f729e72199be4c29
          description: |-
            Account subtype for granular categorization

            * `current_assets` - Current Assets
            * `non_current_assets` - Non-current Assets
            * `current_liabilities` - Current Liabilities
            * `non_current_liabilities` - Non-current Liabilities
            * `share_capital` - Share Capital
            * `share_premium` - Share Premium
            * `reserves` - Reserves
            * `retained_earnings` - Retained Earnings
            * `revenue` - Revenue
            * `other_operating_income` - Other Operating Income
            * `finance_income` - Finance Income
            * `direct_costs` - Direct Costs
            * `operating_expenses` - Operating Expenses
            * `finance_costs` - Finance Costs
            * `income_tax` - Income Tax
        parent_id:
          type: string
          nullable: true
          description: Parent account identifier - accepts UUID, code, or external_id
        description:
          type: string
          description: Human-readable description of account purpose
        external_id:
          type: string
          description: External system identifier. Enables idempotent creation.
          maxLength: 100
        institution_name:
          type: string
          description: Financial institution name (e.g., 'Barclays Bank PLC')
          maxLength: 255
        iban:
          type: string
          description: International Bank Account Number (EU/UK format)
          maxLength: 34
        sort_code:
          type: string
          description: 'UK sort code (flexible format: XX-XX-XX or XXXXXX)'
          maxLength: 8
        account_number_mask:
          type: string
          description: Masked account number for display (e.g., '****4300')
          maxLength: 20
        balance_behavior:
          enum:
          - ''
          - debit_positive
          - credit_positive
          type: string
          x-spec-enum-id: 3fa8710cd3575d95
          description: |-
            Override balance calculation behavior. Leave blank for standard accounting rules.

            * `` - Auto-detect
            * `debit_positive` - Debit Positive
            * `credit_positive` - Credit Positive
        is_cash_account:
          type: boolean
          default: false
          description: Mark as cash or cash equivalent for cash flow purposes
        is_non_cash_expense:
          type: boolean
          default: false
          description: Mark as non-cash expense (depreciation, amortization). Only
            valid for expense accounts.
        custom_fields:
          description: Business-specific metadata as JSON object
      required:
      - code
    AccountDetailsRequest:
      type: object
      description: Validate account_details endpoint input.
      properties:
        parameters:
          type: object
          additionalProperties: {}
      required:
      - parameters
    AccountEntriesResponse:
      type: object
      description: Response wrapper for account entries with opening/closing balances.
      properties:
        account_id:
          type: string
          format: uuid
        account_code:
          type: string
        account_name:
          type: string
        opening_balance_cents:
          type: integer
          description: Balance at start of requested period (or account inception)
        closing_balance_cents:
          type: integer
          description: Balance at end of requested period (or current)
        total_debits_cents:
          type: integer
        total_credits_cents:
          type: integer
        entry_count:
          type: integer
        entries:
          type: array
          items:
            $ref: '#/components/schemas/AccountEntryLine'
          readOnly: true
      required:
      - account_code
      - account_id
      - account_name
      - closing_balance_cents
      - entries
      - entry_count
      - opening_balance_cents
      - total_credits_cents
      - total_debits_cents
    AccountEntryLine:
      type: object
      description: |-
        Serializer for journal entry lines with running balance.
        Used in account entries endpoint.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        journal_entry_id:
          type: string
          format: uuid
          readOnly: true
        journal_entry_date:
          type: string
          format: date
          readOnly: true
        journal_entry_reference:
          type: string
          readOnly: true
        journal_entry_description:
          type: string
          readOnly: true
        line_number:
          type: integer
          readOnly: true
        debit_amount_cents:
          type: integer
          readOnly: true
        credit_amount_cents:
          type: integer
          readOnly: true
        description:
          type: string
          readOnly: true
        external_reference:
          type: string
          readOnly: true
        running_balance_cents:
          type: integer
          description: Return running balance from annotated attribute.
          readOnly: true
        source_type:
          type: string
          nullable: true
          description: Determine source document type from journal entry attachments.
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - credit_amount_cents
      - debit_amount_cents
      - description
      - external_reference
      - id
      - journal_entry_date
      - journal_entry_description
      - journal_entry_id
      - journal_entry_reference
      - line_number
      - running_balance_cents
      - source_type
    AccountFetchResponse:
      type: object
      description: Serializer for account fetch response.
      properties:
        success:
          type: boolean
        message:
          type: string
        accounts_created:
          type: integer
        accounts_updated:
          type: integer
        accounts:
          type: array
          items:
            type: object
            additionalProperties: {}
      required:
      - message
      - success
    AccountIdentifier:
      type: object
      description: Standard account identifier format used across the API.
      properties:
        type:
          type: string
          default: AccountId
          description: Account identifier type (always 'AccountId')
        id:
          type: string
          format: uuid
          description: Account UUID
      required:
      - id
    AccountLinkingRequest:
      type: object
      description: Serializer for account linking request.
      properties:
        bank_link_id:
          type: string
          format: uuid
          description: Bank link UUID
        account_keys:
          type: array
          items:
            type: string
            minLength: 1
          description: List of Plaid account keys to activate (same as Plaid account
            IDs)
      required:
      - account_keys
      - bank_link_id
    AccountLinkingResponse:
      type: object
      description: Serializer for account linking response.
      properties:
        success:
          type: boolean
        message:
          type: string
        linked_accounts:
          type: integer
        deactivated_accounts:
          type: integer
      required:
      - message
      - success
    AccountingPeriod:
      type: object
      description: Full accounting period serializer for list and detail views
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        business_id:
          type: string
          format: uuid
          readOnly: true
        year:
          type: integer
        month:
          type: integer
        period_name:
          type: string
          readOnly: true
        status:
          type: string
          readOnly: true
        start_date:
          type: string
          format: date
          readOnly: true
        end_date:
          type: string
          format: date
          readOnly: true
        is_locked:
          type: boolean
          readOnly: true
        allows_changes:
          type: boolean
          readOnly: true
        requires_override:
          type: boolean
          readOnly: true
        closed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        closed_by:
          type: string
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - allows_changes
      - business_id
      - closed_at
      - closed_by
      - created_at
      - end_date
      - id
      - is_locked
      - month
      - period_name
      - requires_override
      - start_date
      - status
      - updated_at
      - year
    AccountingPeriodRequest:
      type: object
      description: Full accounting period serializer for list and detail views
      properties:
        year:
          type: integer
        month:
          type: integer
      required:
      - month
      - year
    AdditionalSalesTax:
      type: object
      description: Additional sales tax entry (invoice/bill level taxes).
      properties:
        tax_account:
          nullable: true
          description: Tax account identifier (optional)
        amount:
          type: integer
          description: Tax amount in cents
        rate:
          type: string
          format: decimal
          pattern: ^-?\d{0,3}(?:\.\d{0,2})?$
          description: Tax rate percentage (e.g., 20.00 for 20%)
        name:
          type: string
          description: Tax name (e.g., 'VAT', 'GST')
      required:
      - amount
    AssignmentInfo:
      type: object
      description: Serializer for business assignment info.
      properties:
        assigned_at:
          type: string
          format: date
          nullable: true
      required:
      - assigned_at
    BalanceSheet:
      type: object
      description: |-
        Complete Balance Sheet report response.

        Subtype group keys are AccountSubtype.value:
        - "non_current_assets" (from Account.AccountSubtype.NON_CURRENT_ASSETS.value)
        - "current_assets" (from Account.AccountSubtype.CURRENT_ASSETS.value)
        - "current_liabilities" (from Account.AccountSubtype.CURRENT_LIABILITIES.value)
        - "non_current_liabilities" (from Account.AccountSubtype.NON_CURRENT_LIABILITIES.value)
        - "share_capital" (from Account.AccountSubtype.SHARE_CAPITAL.value)
        - "share_premium" (from Account.AccountSubtype.SHARE_PREMIUM.value)
        - "reserves" (from Account.AccountSubtype.RESERVES.value)
        - "retained_earnings" (from Account.AccountSubtype.RETAINED_EARNINGS.value)
      properties:
        business_id:
          type: string
          format: uuid
          description: Business UUID
        as_of_date:
          type: string
          format: date
          description: Balance sheet date (point in time)
        currency:
          type: string
          description: Business base currency
        detail_level:
          enum:
          - summary
          - detailed
          type: string
          x-spec-enum-id: 42d5883c5aa0b3a9
          description: |-
            'summary' or 'detailed'

            * `summary` - summary
            * `detailed` - detailed
        summary:
          allOf:
          - $ref: '#/components/schemas/BalanceSheetSummary'
          description: Calculated Balance Sheet totals
        non_current_assets:
          $ref: '#/components/schemas/BalanceSheetSubtypeGroup'
        current_assets:
          $ref: '#/components/schemas/BalanceSheetSubtypeGroup'
        current_liabilities:
          $ref: '#/components/schemas/BalanceSheetSubtypeGroup'
        non_current_liabilities:
          $ref: '#/components/schemas/BalanceSheetSubtypeGroup'
        share_capital:
          $ref: '#/components/schemas/BalanceSheetSubtypeGroup'
        share_premium:
          $ref: '#/components/schemas/BalanceSheetSubtypeGroup'
        reserves:
          $ref: '#/components/schemas/BalanceSheetSubtypeGroup'
        retained_earnings:
          $ref: '#/components/schemas/BalanceSheetSubtypeGroup'
      required:
      - as_of_date
      - business_id
      - currency
      - detail_level
      - summary
    BalanceSheetLineItem:
      type: object
      description: |-
        Individual account line item in Balance Sheet report.

        Represents a single Account with its cumulative balance as of the report date.
      properties:
        account_id:
          type: string
          format: uuid
          description: Account UUID (from Account.id)
        account_code:
          type: string
          description: Account code (from Account.code)
        account_name:
          type: string
          description: Account name (from Account.custom_name or Account.name)
        value_cents:
          type: integer
          description: Cumulative balance in cents as of as_of_date
      required:
      - account_code
      - account_id
      - account_name
      - value_cents
    BalanceSheetSubtypeGroup:
      type: object
      description: |-
        Grouped accounts by AccountSubtype.

        - display_name: From AccountSubtype.label
        - total_cents: Sum of all line items
        - line_items: Individual accounts with this subtype
      properties:
        display_name:
          type: string
          description: Display name from AccountSubtype.label
        total_cents:
          type: integer
          description: Subtotal in cents
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/BalanceSheetLineItem'
          description: Individual accounts
      required:
      - display_name
      - total_cents
    BalanceSheetSummary:
      type: object
      description: |-
        Calculated Balance Sheet totals.

        Each field is calculated from AccountSubtype totals:
        - total_assets_cents = NON_CURRENT_ASSETS + CURRENT_ASSETS
        - total_liabilities_cents = CURRENT_LIABILITIES + NON_CURRENT_LIABILITIES
        - total_equity_cents = SHARE_CAPITAL + SHARE_PREMIUM + RESERVES + RETAINED_EARNINGS (+ current period P&L)
        - net_assets_cents = total_assets - total_liabilities (should equal total_equity)
      properties:
        total_assets_cents:
          type: integer
          description: Total assets (non-current + current)
        total_non_current_assets_cents:
          type: integer
          description: Sum of AccountSubtype.NON_CURRENT_ASSETS
        total_current_assets_cents:
          type: integer
          description: Sum of AccountSubtype.CURRENT_ASSETS
        total_liabilities_cents:
          type: integer
          description: Total liabilities (current + non-current)
        total_current_liabilities_cents:
          type: integer
          description: Sum of AccountSubtype.CURRENT_LIABILITIES
        total_non_current_liabilities_cents:
          type: integer
          description: Sum of AccountSubtype.NON_CURRENT_LIABILITIES
        total_equity_cents:
          type: integer
          description: Total equity (all equity subtypes + current period P&L)
        net_assets_cents:
          type: integer
          description: Net assets = total_assets - total_liabilities
      required:
      - net_assets_cents
      - total_assets_cents
      - total_current_assets_cents
      - total_current_liabilities_cents
      - total_equity_cents
      - total_liabilities_cents
      - total_non_current_assets_cents
      - total_non_current_liabilities_cents
    BankAccountConnection:
      type: object
      description: |-
        Comprehensive serializer for bank account connections.

        Provides detailed information about connected bank accounts including
        status, balance, sync information, and related business context.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique bank account connection identifier
        account_key:
          type: string
          description: Provider-specific account key for identifying this account
            in their system
          maxLength: 255
        display_name:
          type: string
          description: User-friendly account name (e.g., 'Business Current Account')
          maxLength: 255
        official_name:
          type: string
          description: Official bank account name from the financial institution
          maxLength: 255
        mask:
          type: string
          description: Last 4 digits of account number for identification (e.g., '1234')
          maxLength: 10
        balance:
          type: number
          format: double
          nullable: true
          readOnly: true
          description: Current account balance in decimal format (e.g., 12500.50 for
            £12,500.50) - for backward compatibility
        balance_cents:
          type: integer
          readOnly: true
          description: Current account balance in cents (e.g., 1250050 for £12,500.50)
        currency:
          type: string
          description: Account currency code (GBP, EUR, USD)
          maxLength: 3
        is_active:
          type: boolean
          description: Whether this account connection is active and syncing transactions
            (false if disconnected)
        bank_link_status:
          type: string
          readOnly: true
          description: Bank link connection status (active, revoked, error)
        bank_link_id:
          type: string
          format: uuid
          readOnly: true
          description: Bank link UUID that this account belongs to
        business_id:
          type: string
          format: uuid
          readOnly: true
          description: Business UUID that owns this bank account
        business_name:
          type: string
          readOnly: true
          description: Business name for display purposes
        provider:
          type: string
          readOnly: true
          description: Banking data provider (e.g., plaid, open_banking)
        mapped_account:
          type: string
          format: uuid
          nullable: true
          description: Chart of accounts ID this bank account is mapped to (null if
            not mapped)
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when bank account was first connected
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp of last update to account information
      required:
      - account_key
      - balance
      - balance_cents
      - bank_link_id
      - bank_link_status
      - business_id
      - business_name
      - created_at
      - id
      - provider
      - updated_at
    BankAccountConnectionSummary:
      type: object
      description: |-
        Lightweight serializer for bank account connection summaries.

        Used for list views where detailed information is not needed.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique bank account connection identifier
        display_name:
          type: string
          description: User-friendly account name (e.g., 'Business Current Account')
          maxLength: 255
        official_name:
          type: string
          description: Official bank account name from the financial institution
          maxLength: 255
        mask:
          type: string
          description: Last 4 digits of account number for identification (e.g., '1234')
          maxLength: 10
        balance:
          type: number
          format: double
          nullable: true
          readOnly: true
          description: Current account balance in decimal format (e.g., 12500.50 for
            £12,500.50) - for backward compatibility
        balance_cents:
          type: integer
          readOnly: true
          description: Current account balance in cents (e.g., 1250050 for £12,500.50)
        currency:
          type: string
          description: Account currency code (GBP, EUR, USD)
          maxLength: 3
        is_active:
          type: boolean
          description: Whether this account connection is active and syncing transactions
            (false if disconnected)
        bank_link_status:
          type: string
          readOnly: true
          description: Bank link connection status (active, revoked, error)
        business_name:
          type: string
          readOnly: true
          description: Business name for display purposes
        provider:
          type: string
          readOnly: true
          description: Banking data provider (e.g., plaid, open_banking)
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when bank account was first connected
      required:
      - balance
      - balance_cents
      - bank_link_status
      - business_name
      - created_at
      - id
      - provider
    BankLinkDisconnectResponse:
      type: object
      description: Response serializer for bank link disconnect endpoint
      properties:
        success:
          type: boolean
          description: Whether the disconnect operation was successful
        message:
          type: string
          description: Descriptive message about the operation
        bank_link_id:
          type: string
          format: uuid
          description: UUID of the disconnected bank link
        deactivated_accounts:
          type: integer
          description: Number of bank accounts that were deactivated
      required:
      - bank_link_id
      - deactivated_accounts
      - message
      - success
    BankTransaction:
      type: object
      description: |-
        Serializer for bank transaction list views.
        Contains essential fields for list display with better performance.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique bank transaction identifier
        date:
          type: string
          format: date-time
          description: Transaction date (YYYY-MM-DD format)
        amount:
          type: integer
          description: Transaction amount in cents (unsigned, e.g., 450000 for £4,500.00)
          readOnly: true
        display_amount:
          type: string
          readOnly: true
          description: Formatted transaction amount for display (e.g., '£4,500.00')
        signed_amount:
          type: integer
          description: Signed transaction amount in cents (positive for credit/incoming,
            negative for debit/outgoing)
          readOnly: true
        direction:
          enum:
          - credit
          - debit
          type: string
          x-spec-enum-id: df4966e234dbb91d
          description: |-
            Transaction direction: 'credit' (money in/incoming) or 'debit' (money out/outgoing)

            * `credit` - Credit (Money In)
            * `debit` - Debit (Money Out)
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          x-spec-enum-id: 7e6a70e4775b3009
          description: |-
            Transaction currency code (GBP, EUR, USD)

            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
        counterparty_name:
          type: string
          description: Name of the other party in the transaction (customer/vendor
            name, null if not available)
          maxLength: 255
        merchant_name:
          type: string
          description: Merchant or business name (from card payment data, null if
            not available)
          maxLength: 255
        description:
          type: string
          description: Transaction description from bank feed (e.g., 'Payment for
            Invoice INV-0042')
          maxLength: 500
        categorization_status:
          enum:
          - pending
          - categorized
          - manual_review
          - approved
          type: string
          x-spec-enum-id: af30d82e198cc7fb
          description: |-
            Categorization workflow status: pending, categorized, manual_review, approved

            * `pending` - Pending Review
            * `categorized` - AI Categorized
            * `manual_review` - Requires Manual Review
            * `approved` - Approved
        approval_status:
          enum:
          - pending_approval
          - ai_approved
          - approved
          type: string
          x-spec-enum-id: 7b698985e3218bf3
          description: |-
            Approval status for posting: pending_approval (needs review), ai_approved (auto-approved by AI), approved (human approved). JE triggers when approved.

            * `pending_approval` - Pending Approval
            * `ai_approved` - AI Approved
            * `approved` - Approved
        transaction_type:
          enum:
          - fps
          - bacs
          - chaps
          - direct_debit
          - standing_order
          - sepa_credit
          - sepa_debit
          - sepa_instant
          - card_payment
          - atm_withdrawal
          - bank_transfer
          - fee
          - interest
          - other
          - ''
          type: string
          x-spec-enum-id: 5d65d8aa555eb7d4
          description: |-
            UK/EU bank transaction type: fps (Faster Payments), bacs, chaps, direct_debit, standing_order, sepa_credit, sepa_debit, sepa_instant, card_payment, atm_withdrawal, bank_transfer, fee, interest, other

            * `fps` - Faster Payment
            * `bacs` - BACS Payment
            * `chaps` - CHAPS Payment
            * `direct_debit` - Direct Debit
            * `standing_order` - Standing Order
            * `sepa_credit` - SEPA Credit Transfer
            * `sepa_debit` - SEPA Direct Debit
            * `sepa_instant` - SEPA Instant Payment
            * `card_payment` - Card Payment
            * `atm_withdrawal` - ATM Withdrawal
            * `bank_transfer` - Bank Transfer
            * `fee` - Bank Fee
            * `interest` - Interest
            * `other` - Other
        subcategory:
          allOf:
          - $ref: '#/components/schemas/SubcategoryWithCategory'
          readOnly: true
          nullable: true
          description: Transaction subcategory with nested category details (null
            if not categorized)
        business_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: Business UUID that owns this transaction
        business_name:
          type: string
          readOnly: true
          nullable: true
          description: Business name for display purposes
        account_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: Chart of accounts ID this transaction is categorized to (null
            if not categorized)
        account_code:
          type: string
          readOnly: true
          nullable: true
          description: Account code from chart of accounts (e.g., '1000' for bank
            account)
        account_name:
          type: string
          readOnly: true
          nullable: true
          description: Account name from chart of accounts (e.g., 'Bank - Barclays
            Current')
        bank_account_connection_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: Bank account connection UUID this transaction belongs to
        bank_account_name:
          type: string
          readOnly: true
          nullable: true
          description: Display name of the bank account (e.g., 'Barclays Business
            Current Account')
        bank_account_mask:
          type: string
          readOnly: true
          nullable: true
          description: Last 4 digits of the bank account number (e.g., '1234')
        bank_account_currency:
          type: string
          readOnly: true
          nullable: true
          description: Currency of the bank account (GBP, EUR, USD)
        is_reconciled:
          type: boolean
          readOnly: true
          description: Whether this transaction has been reconciled to invoices/bills/payments
        reconciled_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          description: Timestamp when transaction was first reconciled (null if not
            reconciled)
        reconciled_amount_cents:
          type: integer
          readOnly: true
          description: Total amount reconciled in cents (sum of all confirmed reconciliation
            links)
        remaining_amount_cents:
          type: integer
          readOnly: true
          description: Remaining unreconciled amount in cents (amount - reconciled_amount_cents)
        reconciliations:
          type: array
          items:
            $ref: '#/components/schemas/BankTransactionReconciliationDetail'
          nullable: true
          readOnly: true
          description: List of reconciliation links showing what this transaction
            is matched to (invoices/bills/payments) - only populated in detail view
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when transaction was imported into the system
      required:
      - account_code
      - account_id
      - account_name
      - amount
      - bank_account_connection_id
      - bank_account_currency
      - bank_account_mask
      - bank_account_name
      - business_id
      - business_name
      - created_at
      - date
      - direction
      - display_amount
      - id
      - is_reconciled
      - reconciled_amount_cents
      - reconciled_at
      - reconciliations
      - remaining_amount_cents
      - signed_amount
      - subcategory
    BankTransactionCategoryGroupingResponse:
      type: object
      description: Serializer for documenting the category grouping response structure
        in Swagger.
      properties:
        group_by:
          type: string
          description: 'Grouping method: ''category'' or ''subcategory'''
        summary:
          allOf:
          - $ref: '#/components/schemas/CategoryGroupingSummary'
          description: Summary statistics
        categories:
          type: array
          items:
            $ref: '#/components/schemas/CategoryGroup'
          description: Transactions grouped by category
      required:
      - categories
      - group_by
      - summary
    BankTransactionInfo:
      type: object
      description: Serializer for bank transaction information in source_info.
      properties:
        id:
          type: string
          format: uuid
          description: Bank transaction ID
        description:
          type: string
          description: Transaction description
        date:
          type: string
          format: date
          description: Transaction date
        amount_cents:
          type: integer
          description: Transaction amount in cents
      required:
      - amount_cents
      - date
      - description
      - id
    BankTransactionReconciliationDetail:
      type: object
      description: Detailed reconciliation info for a bank transaction
      properties:
        reconciliation_link_id:
          type: string
          format: uuid
        entity_type:
          type: string
          description: 'Type: payment, bill_payment, receipt, refund_payment, vendor_refund_payment'
        entity_id:
          type: string
          format: uuid
        amount_cents:
          type: integer
        status:
          type: string
        created_at:
          type: string
          format: date-time
        created_by:
          type: string
        notes:
          type: string
      required:
      - amount_cents
      - created_at
      - entity_id
      - entity_type
      - reconciliation_link_id
      - status
    Bill:
      type: object
      description: Main bill serializer for list/fetch responses, aligned with existing
        API style
      properties:
        type:
          type: string
          readOnly: true
          description: Always 'BillData' for type discrimination
        id:
          type: string
          format: uuid
          readOnly: true
        business_id:
          type: string
          format: uuid
          readOnly: true
        external_id:
          type: string
        status:
          type: string
          readOnly: true
          description: 'Bill status: received, partially_paid, paid, voided'
        terms:
          type: string
          readOnly: true
          description: Payment terms (NET_30, NET_60, DUE_ON_RECEIPT, etc.)
        issue_date:
          type: string
          format: date
          description: Date the bill was issued by vendor (from bill_date)
          readOnly: true
        received_at:
          type: string
          format: date-time
          readOnly: true
          description: Date/time bill was received
        due_at:
          type: string
          format: date-time
          readOnly: true
          description: Payment due date/time
        paid_at:
          type: string
          format: date-time
          readOnly: true
          description: Full payment completion date/time
        voided_at:
          type: string
          format: date-time
          readOnly: true
          description: Void action timestamp
        is_overdue:
          type: boolean
          description: True if bill is past due date and has outstanding balance
          example: false
          readOnly: true
        bill_number:
          type: string
        vendor_bill_number:
          type: string
        purchase_order_number:
          type: string
        memo:
          type: string
        reference_numbers: {}
        attachment_urls: {}
        metadata: {}
        currency:
          type: string
          readOnly: true
        vendor:
          allOf:
          - $ref: '#/components/schemas/Vendor'
          readOnly: true
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/BillLineItem'
          readOnly: true
        bill_payment_allocations:
          type: array
          items:
            $ref: '#/components/schemas/BillPaymentAllocationSummary'
          readOnly: true
          description: Payment allocations for this bill
        vendor_credit_allocations:
          type: array
          items:
            $ref: '#/components/schemas/VendorCreditAllocationSummary'
          readOnly: true
          description: Vendor credit note allocations for this bill
        vendor_refund_allocations:
          type: array
          items:
            $ref: '#/components/schemas/VendorRefundAllocationSummary'
          readOnly: true
          description: Vendor refund allocations for this bill
        additional_sales_taxes:
          type: array
          items:
            $ref: '#/components/schemas/AdditionalSalesTax'
          readOnly: true
          description: Additional tax entries not included in line items
        additional_sales_taxes_total:
          type: integer
          description: Total additional sales taxes in cents
          readOnly: true
        subtotal:
          type: integer
          description: Subtotal amount in cents before taxes
          readOnly: true
        total_amount:
          type: integer
          description: Total bill amount in cents including taxes
          readOnly: true
        outstanding_balance:
          type: integer
          description: Outstanding balance in cents
          readOnly: true
        paid_by_bank_payments:
          type: integer
          description: Amount paid via bank payments in cents (completed only)
          readOnly: true
        paid_by_credits:
          type: integer
          description: Amount paid via vendor credit notes in cents
          readOnly: true
        needs_reconciliation:
          type: boolean
          description: True if has unreconciled bank payments
          readOnly: true
        document:
          allOf:
          - $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: Latest document with presigned URL
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - additional_sales_taxes
      - additional_sales_taxes_total
      - bill_payment_allocations
      - business_id
      - created_at
      - currency
      - document
      - due_at
      - id
      - is_overdue
      - issue_date
      - line_items
      - needs_reconciliation
      - outstanding_balance
      - paid_at
      - paid_by_bank_payments
      - paid_by_credits
      - received_at
      - status
      - subtotal
      - terms
      - total_amount
      - type
      - updated_at
      - vendor
      - vendor_credit_allocations
      - vendor_refund_allocations
      - voided_at
    BillCreateAPIRequest:
      type: object
      description: Bill creation serializer. Creates a Bill with line items.
      properties:
        external_id:
          type: string
          minLength: 1
          description: Your unique identifier for this bill (used for idempotency)
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/BillLineItemCreateRequest'
          description: Array of line items for this bill (at least one required)
        vendor_id:
          type: string
          format: uuid
          nullable: true
          description: UUID of existing vendor (use this OR vendor_external_id, not
            both)
        vendor_external_id:
          type: string
          description: External vendor ID - will auto-create vendor if not found
        bill_number:
          type: string
          description: Your internal bill tracking number
        vendor_bill_number:
          type: string
          description: Vendor's invoice/bill number from their system
        purchase_order_number:
          type: string
          description: Purchase order number if applicable
        memo:
          type: string
          description: Description or notes for this bill
        reference_numbers:
          type: array
          items:
            type: string
            minLength: 1
          description: Array of additional reference numbers for tracking
        attachment_urls:
          type: array
          items:
            type: string
            minLength: 1
          description: Array of URLs to bill documents/PDFs
        bill_date:
          type: string
          format: date
          description: 'Date bill was issued by vendor (ISO date: YYYY-MM-DD)'
        received_at:
          type: string
          format: date-time
          description: Date/time bill was received (ISO 8601 format)
        due_at:
          type: string
          format: date-time
          description: Payment due date/time (ISO 8601 format)
        approved_at:
          type: string
          format: date-time
          nullable: true
          description: Date/time bill was approved (triggers journal entry creation)
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          - ''
          type: string
          x-spec-enum-id: 7e6a70e4775b3009
          description: |-
            Bill currency (e.g., GBP, EUR, USD)

            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
        document:
          allOf:
          - $ref: '#/components/schemas/BillDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
      required:
      - external_id
      - line_items
    BillDocumentUploadRequest:
      type: object
      description: |-
        Bill specific document upload payload.

        Inherits from BaseFileUploadSerializer pattern for file validation.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: purchase_invoice
        upload_source:
          type: string
        metadata: {}
        tags: {}
    BillLineItem:
      type: object
      description: |-
        Serializer for bill line items in listing responses.

        Performance Note:
        - Accesses bill.id and bill.currency which require the bill relationship
        - When used in BillSerializer (via many=True), the parent bill is already loaded
        - For standalone usage, ensure queryset uses: .select_related('bill')
        - For nested usage in Bill list, ensure: .prefetch_related(Prefetch('line_items', queryset=BillLineItem.objects.select_related('bill')))
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        bill_id:
          type: string
          format: uuid
          readOnly: true
        account_identifier:
          allOf:
          - $ref: '#/components/schemas/AccountIdentifier'
          nullable: true
          readOnly: true
        description:
          type: string
        product:
          type: string
        currency:
          type: string
          readOnly: true
        unit_price:
          type: integer
          description: Unit price in cents
          readOnly: true
        quantity:
          type: number
          format: float
          description: Return quantity as float
          readOnly: true
        subtotal:
          type: integer
          description: Subtotal before taxes in cents
          readOnly: true
        sales_taxes_total:
          type: integer
          description: Total tax amount in cents
          readOnly: true
        total_amount:
          type: integer
          description: Total amount including taxes in cents
          readOnly: true
        tax_rate:
          type: number
          format: float
          readOnly: true
          description: Tax rate as a percentage (e.g., 20.0 for 20%)
      required:
      - account_identifier
      - bill_id
      - currency
      - id
      - quantity
      - sales_taxes_total
      - subtotal
      - tax_rate
      - total_amount
      - unit_price
    BillLineItemCreateRequest:
      type: object
      description: Line item input for bill creation requests
      properties:
        description:
          type: string
        account_identifier:
          nullable: true
          description: Expense account identifier, e.g., {"type":"AccountId","id":"..."}
        product:
          type: string
        quantity:
          type: number
          format: double
        unit_price:
          type: integer
          description: Unit price in cents
        sales_taxes:
          type: array
          items:
            type: object
            additionalProperties: {}
      required:
      - quantity
      - unit_price
    BillLineItemRequest:
      type: object
      description: |-
        Serializer for bill line items in listing responses.

        Performance Note:
        - Accesses bill.id and bill.currency which require the bill relationship
        - When used in BillSerializer (via many=True), the parent bill is already loaded
        - For standalone usage, ensure queryset uses: .select_related('bill')
        - For nested usage in Bill list, ensure: .prefetch_related(Prefetch('line_items', queryset=BillLineItem.objects.select_related('bill')))
      properties:
        description:
          type: string
        product:
          type: string
    BillPaymentAllocation:
      type: object
      description: Serializer for bill payment allocation details. All amounts in
        cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique allocation identifier
        bill_id:
          type: string
          format: uuid
          description: Bill this allocation applies to
        bill_number:
          type: string
          readOnly: true
          description: Bill number
        vendor_bill_number:
          type: string
          readOnly: true
          description: Vendor's bill number
        bill_status:
          type: string
          description: Current bill status
          readOnly: true
        amount_cents:
          type: integer
          description: Allocation amount in cents
        description:
          type: string
          description: Allocation description
        allocation_date:
          type: string
          format: date-time
          readOnly: true
          description: When allocation was created
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Creation timestamp
      required:
      - allocation_date
      - amount_cents
      - bill_id
      - bill_number
      - bill_status
      - created_at
      - id
      - vendor_bill_number
    BillPaymentAllocationCreateRequest:
      type: object
      description: Serializer for creating bill payment allocations
      properties:
        bill_id:
          type: string
          format: uuid
          description: UUID of the bill to allocate payment to
        amount_cents:
          type: integer
          minimum: 1
          description: Amount to allocate to this bill in cents (cannot exceed bill
            outstanding balance)
        description:
          type: string
          description: Optional description for this allocation
          maxLength: 500
      required:
      - amount_cents
      - bill_id
    BillPaymentAllocationRequest:
      type: object
      description: Serializer for bill payment allocation details. All amounts in
        cents.
      properties:
        bill_id:
          type: string
          format: uuid
          description: Bill this allocation applies to
        amount_cents:
          type: integer
          description: Allocation amount in cents
        description:
          type: string
          description: Allocation description
      required:
      - amount_cents
      - bill_id
    BillPaymentAllocationSummary:
      type: object
      description: Payment allocation summary for bill detail view.
      properties:
        amount_cents:
          type: integer
        payment_date:
          type: string
          format: date
        payment_method:
          type: string
        bill_payment_id:
          type: string
          format: uuid
      required:
      - amount_cents
      - bill_payment_id
      - payment_date
      - payment_method
    BillPaymentCancelResponse:
      type: object
      description: Response serializer for bill payment cancellation
      properties:
        message:
          type: string
          description: Status message
        payment_id:
          type: string
          format: uuid
          description: UUID of the cancelled payment
        status:
          type: string
          description: New status of the payment
        updated_at:
          type: string
          format: date-time
          description: When the payment was updated
      required:
      - message
      - payment_id
      - status
      - updated_at
    BillPaymentCreateRequest:
      type: object
      description: |-
        Serializer for creating bill payments with allocations.

        This follows the same pattern as vendor refund payments and invoice payments,
        where allocations are embedded in the payment creation request.
      properties:
        vendor_id:
          type: string
          format: uuid
          description: UUID of the vendor receiving the payment (must exist in business)
        amount_cents:
          type: integer
          minimum: 1
          description: Total payment amount in cents (e.g., 450000 for £4,500.00)
        currency:
          type: string
          minLength: 1
          default: GBP
          description: Payment currency (must match business base currency, defaults
            to GBP)
          maxLength: 3
        payment_method:
          enum:
          - bank_transfer
          - ach
          - wire
          - check
          - credit_card
          - cash
          - other
          type: string
          x-spec-enum-id: e41885a675157233
          default: bank_transfer
          description: |-
            Payment method: bank_transfer, ach, wire, check, credit_card, cash, or other

            * `bank_transfer` - bank_transfer
            * `ach` - ach
            * `wire` - wire
            * `check` - check
            * `credit_card` - credit_card
            * `cash` - cash
            * `other` - other
        payment_date:
          type: string
          format: date
          description: 'Date when payment was made (ISO date format: YYYY-MM-DD)'
        payment_reference:
          type: string
          description: Your internal payment reference or transaction ID
          maxLength: 100
        check_number:
          type: string
          description: Check number (required if payment_method is check)
          maxLength: 50
        description:
          type: string
          description: Description of the payment
        memo:
          type: string
          description: Additional notes or memo for the payment
        processing_fee_cents:
          type: integer
          minimum: 0
          default: 0
          description: Processing fee in cents (defaults to 0)
        external_id:
          type: string
          description: Your unique identifier for idempotency (prevents duplicate
            payments)
          maxLength: 255
        metadata:
          description: Custom key-value pairs for additional payment context
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/BillPaymentAllocationCreateRequest'
          description: Array of bills to allocate this payment to
      required:
      - amount_cents
      - vendor_id
    BillPaymentList:
      type: object
      description: Serializer for listing bill payments. All amounts in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique bill payment identifier
        vendor_id:
          type: string
          format: uuid
          readOnly: true
          description: Vendor receiving payment
        vendor_name:
          type: string
          readOnly: true
          description: Vendor display name
        payment_reference:
          type: string
          readOnly: true
          description: Payment reference
        payment_date:
          type: string
          format: date
          readOnly: true
          description: Payment date
        amount_cents:
          type: integer
          readOnly: true
          description: Payment amount in cents
        currency:
          type: string
          readOnly: true
          description: Payment currency
        payment_method:
          type: string
          readOnly: true
          description: Payment method
        status:
          type: string
          readOnly: true
          description: Payment status
        allocated_amount_cents:
          type: integer
          readOnly: true
          description: Allocated amount in cents
        unallocated_amount_cents:
          type: integer
          readOnly: true
          description: Unallocated amount in cents
        is_fully_allocated:
          type: boolean
          readOnly: true
          description: Whether fully allocated to bills
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/BillPaymentAllocation'
          readOnly: true
          description: Bill allocations for this payment
        reconciled_bank_transactions:
          type: array
          items:
            $ref: '#/components/schemas/EntityReconciliationDetail'
          readOnly: true
          description: Bank transactions this payment is reconciled to
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Update timestamp
      required:
      - allocated_amount_cents
      - allocations
      - amount_cents
      - created_at
      - currency
      - id
      - is_fully_allocated
      - payment_date
      - payment_method
      - payment_reference
      - reconciled_bank_transactions
      - status
      - unallocated_amount_cents
      - updated_at
      - vendor_id
      - vendor_name
    BillPaymentResponse:
      type: object
      description: |-
        Detailed response serializer for bill payment with all related data.

        Returns payment details along with vendor info and allocations.
        All amounts in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique bill payment identifier
        business_id:
          type: string
          format: uuid
          readOnly: true
          description: Business this payment belongs to
        vendor_id:
          type: string
          format: uuid
          readOnly: true
          description: Vendor receiving the payment
        vendor_name:
          type: string
          readOnly: true
          description: Vendor display name
        payment_reference:
          type: string
          readOnly: true
          description: Payment reference or transaction ID
        external_id:
          type: string
          readOnly: true
          description: Your external identifier for this payment
        processor_payment_id:
          type: string
          readOnly: true
          description: Payment processor transaction ID (e.g., Stripe ID)
        check_number:
          type: string
          readOnly: true
          description: Check number if payment method is check
        amount_cents:
          type: integer
          readOnly: true
          description: Payment amount in cents
        currency:
          type: string
          readOnly: true
          description: Payment currency (e.g., GBP, EUR, USD)
        processing_fee_cents:
          type: integer
          readOnly: true
          description: Processing fee in cents
        net_amount_cents:
          type: integer
          readOnly: true
          description: Net amount after fees in cents
        allocated_amount_cents:
          type: integer
          readOnly: true
          description: Allocated amount in cents
        unallocated_amount_cents:
          type: integer
          readOnly: true
          description: Unallocated amount in cents
        is_fully_allocated:
          type: boolean
          readOnly: true
          description: Whether payment is fully allocated to bills
        payment_method:
          type: string
          readOnly: true
          description: Payment method used (bank_transfer, check, wire, etc.)
        status:
          type: string
          readOnly: true
          description: Payment status (pending, processing, completed, failed, cancelled)
        payment_date:
          type: string
          format: date
          readOnly: true
          description: Date payment was made
        value_date:
          type: string
          format: date
          readOnly: true
          description: Value date for accounting purposes
        submitted_at:
          type: string
          format: date-time
          readOnly: true
          description: When payment was submitted for processing
        completed_at:
          type: string
          format: date-time
          readOnly: true
          description: When payment processing completed
        failed_at:
          type: string
          format: date-time
          readOnly: true
          description: When payment failed (if applicable)
        description:
          type: string
          readOnly: true
          description: Payment description
        memo:
          type: string
          readOnly: true
          description: Additional notes or memo
        failure_reason:
          type: string
          readOnly: true
          description: Reason for failure (if status=failed)
        metadata:
          readOnly: true
          description: Custom key-value pairs
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/BillPaymentAllocation'
          readOnly: true
          description: Bill allocations for this payment
        vendor_refund_allocations:
          type: array
          items:
            $ref: '#/components/schemas/BillPaymentVendorRefundAllocationSummary'
          readOnly: true
          description: Vendor refund allocations linked to this payment
        reconciled_bank_transactions:
          type: array
          items:
            $ref: '#/components/schemas/EntityReconciliationDetail'
          readOnly: true
          description: Bank transactions this payment is reconciled to
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Payment creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
      required:
      - allocated_amount_cents
      - allocations
      - amount_cents
      - business_id
      - check_number
      - completed_at
      - created_at
      - currency
      - description
      - external_id
      - failed_at
      - failure_reason
      - id
      - is_fully_allocated
      - memo
      - metadata
      - net_amount_cents
      - payment_date
      - payment_method
      - payment_reference
      - processing_fee_cents
      - processor_payment_id
      - reconciled_bank_transactions
      - status
      - submitted_at
      - unallocated_amount_cents
      - updated_at
      - value_date
      - vendor_id
      - vendor_name
      - vendor_refund_allocations
    BillPaymentVendorRefundAllocationSummary:
      type: object
      description: Vendor refund allocation summary for bill payment detail view -
        shows vendor refunds that used this payment.
      properties:
        vendor_refund_id:
          type: string
          format: uuid
        reference_number:
          type: string
        amount_cents:
          type: integer
        allocated_at:
          type: string
          format: date-time
      required:
      - allocated_at
      - amount_cents
      - vendor_refund_id
    BillReconciliationRequestRequest:
      type: object
      description: Request serializer for bill payment reconciliation
      properties:
        notes:
          type: string
          description: Optional notes for the reconciliation
          maxLength: 500
        evidence:
          type: object
          additionalProperties: {}
          description: Supporting evidence for the reconciliation
        created_by:
          enum:
          - api
          - manual
          - auto
          - import
          type: string
          x-spec-enum-id: 5993daf453316fc6
          default: api
          description: |-
            Source of reconciliation (api, manual, auto, import)

            * `api` - api
            * `manual` - manual
            * `auto` - auto
            * `import` - import
        bill_id:
          type: string
          format: uuid
          description: Bill ID to reconcile
        payment_method:
          enum:
          - bank_transfer
          - credit_card
          - debit_card
          - ach
          - check
          - cash
          - wire
          - paypal
          - stripe
          - other
          type: string
          x-spec-enum-id: 6a4918e6dc1589b2
          default: bank_transfer
          description: |-
            Payment method for the reconciliation

            * `bank_transfer` - bank_transfer
            * `credit_card` - credit_card
            * `debit_card` - debit_card
            * `ach` - ach
            * `check` - check
            * `cash` - cash
            * `wire` - wire
            * `paypal` - paypal
            * `stripe` - stripe
            * `other` - other
        amount_cents:
          type: integer
          minimum: 1
          nullable: true
          description: Amount to reconcile in cents. If not provided, uses min(outstanding,
            bank_remaining).
      required:
      - bill_id
    BillRequest:
      type: object
      description: Main bill serializer for list/fetch responses, aligned with existing
        API style
      properties:
        external_id:
          type: string
        bill_number:
          type: string
        vendor_bill_number:
          type: string
        purchase_order_number:
          type: string
        memo:
          type: string
        reference_numbers: {}
        attachment_urls: {}
        metadata: {}
    BillStats:
      type: object
      description: Statistics for purchase bills.
      properties:
        all:
          type: integer
          description: Total number of bills
        unpaid:
          type: integer
          description: Number of unpaid bills (received + partially_paid)
        paid:
          type: integer
          description: Number of fully paid bills
      required:
      - all
      - paid
      - unpaid
    BillUnreconciliationRequestRequest:
      type: object
      description: Request serializer for bill payment unreconciliation
      properties:
        bill_id:
          type: string
          format: uuid
          description: Bill ID to unreconcile
      required:
      - bill_id
    BillUpdateAPIRequest:
      type: object
      description: Bill update serializer. Applies partial updates to a Bill, and
        replaces line items if provided.
      properties:
        vendor_id:
          type: string
          format: uuid
          nullable: true
          description: Updated vendor UUID (cannot change if bill has payments)
        vendor_external_id:
          type: string
          description: Updated vendor external ID
        external_id:
          type: string
          description: Updated external identifier (must remain unique)
        bill_number:
          type: string
          description: Updated internal bill number
        vendor_bill_number:
          type: string
          description: Updated vendor invoice number
        purchase_order_number:
          type: string
          description: Updated PO number
        memo:
          type: string
          description: Updated description or notes
        reference_numbers:
          type: array
          items:
            type: string
            minLength: 1
          description: Updated reference numbers array
        attachment_urls:
          type: array
          items:
            type: string
            minLength: 1
          description: Updated document URLs array
        received_at:
          type: string
          format: date-time
          nullable: true
          description: Updated received date/time
        due_at:
          type: string
          format: date-time
          nullable: true
          description: Updated payment due date/time
        approved_at:
          type: string
          format: date-time
          nullable: true
          description: Date/time bill was approved (triggers journal entry creation)
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          - ''
          type: string
          x-spec-enum-id: 7e6a70e4775b3009
          description: |-
            Updated currency (cannot change if bill has financial data)

            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/BillUpdateLineItemRequest'
          description: Updated line items array (replaces all existing)
        bill_terms:
          type: string
          description: Updated payment terms (NET_30, NET_60, DUE_ON_RECEIPT)
        document:
          allOf:
          - $ref: '#/components/schemas/BillDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    BillUpdateLineItemRequest:
      type: object
      description: Line item input for bill update requests (full replacement of line
        items when provided)
      properties:
        description:
          type: string
        account_identifier:
          nullable: true
          description: Expense account identifier, e.g., {"type":"AccountId","id":"..."}
        product:
          type: string
        quantity:
          type: number
          format: double
        unit_price:
          type: integer
          description: Unit price in cents
        sales_taxes:
          type: array
          items:
            type: object
            additionalProperties: {}
      required:
      - quantity
      - unit_price
    Business:
      type: object
      description: Full business serializer for list and detail views
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique identifier for the business
        external_id:
          type: string
          description: Your unique identifier for this business
        legal_name:
          type: string
          description: Legal registered name of the business
          maxLength: 255
        name:
          type: string
          description: Display name for the business (defaults to legal_name)
          maxLength: 255
        entity_type:
          type: string
          description: Business entity type (e.g., 'limited', 'gmbh', 'bv')
        phone_number:
          type: string
          description: Business phone number
        tin:
          type: string
          description: Tax identification number (other than VAT)
        vat_number:
          type: string
          description: EU VAT registration number
        company_number:
          type: string
          description: Company registration number (e.g., Companies House number for
            UK)
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code (e.g., GB, DE, NL, MY, SG)
          maxLength: 2
        province:
          type: string
          description: Province or state within the country
          maxLength: 100
        eu_nace_industry_code:
          type: string
          description: European NACE industry classification code
          maxLength: 10
        email:
          type: string
          format: email
          description: Primary email address for the business
        base_currency:
          type: string
          description: Base currency for accounting (ISO 4217 code)
          maxLength: 3
        accounting_method:
          type: string
          description: 'Accounting method: ''cash'' or ''accrual'''
          maxLength: 20
        fiscal_year_end:
          type: string
          format: date
          description: Fiscal year end date
        activation_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was activated
        is_active:
          type: boolean
          readOnly: true
          description: Whether the business is active (false if archived)
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was last updated
        metadata:
          description: Custom JSON metadata for partner-specific data
      required:
      - accounting_method
      - activation_at
      - base_currency
      - country
      - created_at
      - email
      - fiscal_year_end
      - id
      - is_active
      - legal_name
      - updated_at
    BusinessList:
      type: object
      description: Lightweight serializer for business list view
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique identifier for the business
        external_id:
          type: string
          readOnly: true
          description: Your unique identifier for this business
        name:
          type: string
          readOnly: true
          description: Display name for the business
        legal_name:
          type: string
          readOnly: true
          description: Legal registered name of the business
        entity_type:
          type: string
          readOnly: true
          description: Business entity type (e.g., 'limited', 'gmbh', 'bv')
        country:
          type: string
          readOnly: true
          description: ISO 3166-1 alpha-2 country code
        province:
          type: string
          readOnly: true
          description: Province or state within the country
        eu_nace_industry_code:
          type: string
          readOnly: true
          description: European NACE industry classification code
        is_active:
          type: boolean
          readOnly: true
          description: Whether the business is active (false if archived)
        activation_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was activated
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was last updated
        vat_number:
          type: string
          readOnly: true
          description: EU VAT registration number
        company_number:
          type: string
          readOnly: true
          description: Company registration number (e.g., Companies House number for
            UK)
        tax_id:
          type: string
          readOnly: true
          description: Tax identification number (other than VAT)
        base_currency:
          type: string
          readOnly: true
          description: Base currency for accounting (ISO 4217 code)
      required:
      - activation_at
      - base_currency
      - company_number
      - country
      - created_at
      - entity_type
      - eu_nace_industry_code
      - external_id
      - id
      - is_active
      - legal_name
      - name
      - province
      - tax_id
      - updated_at
      - vat_number
    BusinessMetrics:
      type: object
      description: Serializer for business task metrics.
      properties:
        open_tasks_count:
          type: integer
        tasks_in_review_count:
          type: integer
        overdue_tasks_count:
          type: integer
        last_activity_date:
          type: string
          format: date-time
          nullable: true
      required:
      - last_activity_date
      - open_tasks_count
      - overdue_tasks_count
      - tasks_in_review_count
    BusinessRequest:
      type: object
      description: Full business serializer for list and detail views
      properties:
        external_id:
          type: string
          description: Your unique identifier for this business
        legal_name:
          type: string
          minLength: 1
          description: Legal registered name of the business
          maxLength: 255
        name:
          type: string
          description: Display name for the business (defaults to legal_name)
          maxLength: 255
        entity_type:
          type: string
          description: Business entity type (e.g., 'limited', 'gmbh', 'bv')
        phone_number:
          type: string
          description: Business phone number
        tin:
          type: string
          description: Tax identification number (other than VAT)
        vat_number:
          type: string
          description: EU VAT registration number
        company_number:
          type: string
          description: Company registration number (e.g., Companies House number for
            UK)
        country:
          type: string
          minLength: 1
          description: ISO 3166-1 alpha-2 country code (e.g., GB, DE, NL, MY, SG)
          maxLength: 2
        province:
          type: string
          description: Province or state within the country
          maxLength: 100
        eu_nace_industry_code:
          type: string
          description: European NACE industry classification code
          maxLength: 10
        email:
          type: string
          format: email
          minLength: 1
          description: Primary email address for the business
        base_currency:
          type: string
          minLength: 1
          description: Base currency for accounting (ISO 4217 code)
          maxLength: 3
        accounting_method:
          type: string
          minLength: 1
          description: 'Accounting method: ''cash'' or ''accrual'''
          maxLength: 20
        fiscal_year_end:
          type: string
          format: date
          description: Fiscal year end date
        metadata:
          description: Custom JSON metadata for partner-specific data
      required:
      - accounting_method
      - base_currency
      - country
      - email
      - fiscal_year_end
      - legal_name
    BusinessTokenResponse:
      type: object
      description: Serializer for business-scoped token response
      properties:
        access_token:
          type: string
          description: Business-scoped JWT Bearer token
        token_type:
          type: string
          default: Bearer
          description: Token type (always 'Bearer')
        expires_in:
          type: integer
          description: Token expiration time in seconds
        scope:
          type: string
          description: Token scope (always 'business_access')
        business_id:
          type: string
          format: uuid
          description: ID of the business this token is scoped to
      required:
      - access_token
      - business_id
      - expires_in
      - scope
    CashFlowLineItem:
      type: object
      description: |-
        Individual account line item in Cash Flow Statement.

        Represents a single Account with its movement during the period.
      properties:
        account_id:
          type: string
          format: uuid
          description: Account UUID
        account_code:
          type: string
          description: Account code
        account_name:
          type: string
          description: Account name
        value_cents:
          type: integer
          description: Movement amount in cents (positive = inflow, negative = outflow)
      required:
      - account_code
      - account_id
      - account_name
      - value_cents
    CashFlowSection:
      type: object
      description: |-
        A section within Cash Flow Statement (e.g., Non-cash Adjustments, Investing Activities).

        Contains display name, total, and optionally line items.
      properties:
        display_name:
          type: string
          description: Section display name
        total_cents:
          type: integer
          description: Section total in cents
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/CashFlowLineItem'
          description: Individual account movements
      required:
      - display_name
      - total_cents
    CashFlowStatement:
      type: object
      description: |-
        Complete Cash Flow Statement response (IAS 7 Indirect Method).

        Always includes:
        - Summary metrics
        - Cash reconciliation check

        When detail_level='detailed', also includes:
        - Operating activities breakdown
        - Investing activities by account
        - Financing activities by account
      properties:
        business_id:
          type: string
          format: uuid
          description: Business UUID
        start_date:
          type: string
          format: date
          description: Report period start date
        end_date:
          type: string
          format: date
          description: Report period end date
        currency:
          type: string
          description: Business base currency (ISO 4217)
        detail_level:
          enum:
          - summary
          - detailed
          type: string
          x-spec-enum-id: 42d5883c5aa0b3a9
          description: |-
            'summary' or 'detailed'

            * `summary` - summary
            * `detailed` - detailed
        summary:
          allOf:
          - $ref: '#/components/schemas/CashFlowSummary'
          description: Cash flow summary metrics
        cash_reconciliation:
          allOf:
          - $ref: '#/components/schemas/CashReconciliation'
          description: Cash reconciliation check (Opening + Change = Closing)
        operating_activities:
          allOf:
          - $ref: '#/components/schemas/OperatingActivities'
          description: Operating activities breakdown (detailed view only)
        investing_activities:
          allOf:
          - $ref: '#/components/schemas/CashFlowSection'
          description: Investing activities by account (detailed view only)
        financing_activities:
          allOf:
          - $ref: '#/components/schemas/CashFlowSection'
          description: Financing activities by account (detailed view only)
      required:
      - business_id
      - cash_reconciliation
      - currency
      - detail_level
      - end_date
      - start_date
      - summary
    CashFlowSummary:
      type: object
      description: |-
        Cash Flow Statement summary metrics.

        Per IAS 7, cash flows are classified into:
        - Operating: Cash from core business operations
        - Investing: Cash from acquisition/disposal of long-term assets
        - Financing: Cash from changes in equity and borrowings
      properties:
        net_cash_from_operating_cents:
          type: integer
          description: Net cash from operating activities (Net Profit + Non-cash +
            Working Capital changes)
        net_cash_from_investing_cents:
          type: integer
          description: Net cash from investing activities (fixed asset purchases/sales)
        net_cash_from_financing_cents:
          type: integer
          description: Net cash from financing activities (equity + debt changes)
        net_change_in_cash_cents:
          type: integer
          description: Total change in cash = Operating + Investing + Financing
        opening_cash_cents:
          type: integer
          description: Cash balance at period start
        closing_cash_cents:
          type: integer
          description: Cash balance at period end
      required:
      - closing_cash_cents
      - net_cash_from_financing_cents
      - net_cash_from_investing_cents
      - net_cash_from_operating_cents
      - net_change_in_cash_cents
      - opening_cash_cents
    CashReconciliation:
      type: object
      description: |-
        Cash reconciliation check per IAS 7.45.

        Validates that: Opening Cash + Net Change = Closing Cash
      properties:
        opening_cash_cents:
          type: integer
          description: Cash balance at period start
        net_change_cents:
          type: integer
          description: Total change in cash during period
        calculated_closing_cents:
          type: integer
          description: Opening + Net Change (should equal actual)
        actual_closing_cents:
          type: integer
          description: Actual cash balance at period end
        reconciles:
          type: boolean
          description: True if calculated equals actual closing cash
      required:
      - actual_closing_cents
      - calculated_closing_cents
      - net_change_cents
      - opening_cash_cents
      - reconciles
    CategoryGroup:
      type: object
      description: Serializer for each category group in the response.
      properties:
        name:
          type: string
          description: Category name ('Uncategorized' for transactions without category)
        metadata:
          allOf:
          - $ref: '#/components/schemas/CategoryMetadata'
          description: Category statistics
        transactions:
          type: array
          items:
            $ref: '#/components/schemas/BankTransaction'
          description: Transactions in this category
      required:
      - metadata
      - name
      - transactions
    CategoryGroupingSummary:
      type: object
      description: Summary information for the entire response.
      properties:
        total_categories:
          type: integer
          description: Total number of categories
        total_amount:
          type: integer
          description: Total amount across all transactions in cents
      required:
      - total_amount
      - total_categories
    CategoryListResponse:
      type: object
      description: |-
        Response serializer for category list endpoint.

        Returns paginated list of categories with their subcategories.
      properties:
        count:
          type: integer
          description: Total number of categories
        results:
          type: array
          items:
            $ref: '#/components/schemas/TransactionCategoryWithSubcategories'
          description: List of categories with subcategories
      required:
      - count
      - results
    CategoryMetadata:
      type: object
      description: Metadata for each category in grouped response.
      properties:
        transaction_count:
          type: integer
          description: Number of transactions in this category
        total_amount:
          type: integer
          description: Total amount for this category in cents
        average_amount:
          type: integer
          description: Average transaction amount for this category in cents
        percentage_of_total:
          type: string
          format: decimal
          pattern: ^-?\d{0,3}(?:\.\d{0,2})?$
          description: Percentage of total amount
      required:
      - average_amount
      - percentage_of_total
      - total_amount
      - transaction_count
    ChartOfAccountDetail:
      type: object
      description: Detailed serializer for account with additional information.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique account identifier
        code:
          type: string
          readOnly: true
          description: Account code from chart of accounts (e.g., '1000', '4000')
        name:
          type: string
          description: Account name from chart of accounts
          readOnly: true
        currency:
          type: string
          description: Account currency from business base currency (GBP, EUR, USD)
          readOnly: true
        account_type:
          enum:
          - asset
          - liability
          - equity
          - revenue
          - expense
          type: string
          x-spec-enum-id: bee27527493b2230
          readOnly: true
          description: |-
            Account type code (asset, liability, equity, revenue, expense)

            * `asset` - Asset
            * `liability` - Liability
            * `equity` - Equity
            * `revenue` - Revenue
            * `expense` - Expense
        account_type_display:
          type: string
          nullable: true
          description: Human-readable account type (e.g., 'Current Asset', 'Revenue')
          readOnly: true
        account_subtype:
          enum:
          - current_assets
          - non_current_assets
          - current_liabilities
          - non_current_liabilities
          - share_capital
          - share_premium
          - reserves
          - retained_earnings
          - revenue
          - other_operating_income
          - finance_income
          - direct_costs
          - operating_expenses
          - finance_costs
          - income_tax
          type: string
          x-spec-enum-id: f729e72199be4c29
          readOnly: true
          description: |-
            Account subtype code for more granular classification (bank, cash, etc.)

            * `current_assets` - Current Assets
            * `non_current_assets` - Non-current Assets
            * `current_liabilities` - Current Liabilities
            * `non_current_liabilities` - Non-current Liabilities
            * `share_capital` - Share Capital
            * `share_premium` - Share Premium
            * `reserves` - Reserves
            * `retained_earnings` - Retained Earnings
            * `revenue` - Revenue
            * `other_operating_income` - Other Operating Income
            * `finance_income` - Finance Income
            * `direct_costs` - Direct Costs
            * `operating_expenses` - Operating Expenses
            * `finance_costs` - Finance Costs
            * `income_tax` - Income Tax
        account_subtype_display:
          type: string
          nullable: true
          description: Account subtype for more granular classification
          readOnly: true
        parent_account_code:
          type: string
          nullable: true
          description: Parent account code if this is a sub-account (null for top-level
            accounts)
          readOnly: true
        current_balance:
          type: integer
          description: Current balance in cents
          readOnly: true
        current_balance_formatted:
          type: string
          description: Formatted balance with currency symbol (e.g., '£12,500.50')
          readOnly: true
        debit_balance:
          type: integer
          description: Debit balance in cents
          readOnly: true
        credit_balance:
          type: integer
          description: Credit balance in cents
          readOnly: true
        period_balance:
          type: integer
          description: Period balance in cents (null if no period filter applied)
          readOnly: true
        period_balance_formatted:
          type: string
          nullable: true
          description: Formatted period balance with currency symbol (null if no period
            filter)
          readOnly: true
        has_children:
          type: boolean
          description: Whether this account has sub-accounts (nested hierarchy)
          readOnly: true
        hierarchy_level:
          type: integer
          description: Depth in account hierarchy (0 for root accounts)
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
          description: Whether this account is active and accepting transactions
        description:
          type: string
          readOnly: true
          description: Detailed account description
        institution_name:
          type: string
          readOnly: true
          nullable: true
          description: Bank institution name (for bank accounts only)
        iban:
          type: string
          readOnly: true
          nullable: true
          description: International Bank Account Number (for bank accounts)
        sort_code:
          type: string
          readOnly: true
          nullable: true
          description: 'UK bank sort code (for UK bank accounts, format: XX-XX-XX)'
        account_number_mask:
          type: string
          readOnly: true
          nullable: true
          description: Masked account number showing last 4 digits (e.g., '****5555')
        total_debits:
          type: integer
          description: Total number of debit transactions (count, not amount)
          readOnly: true
        total_credits:
          type: integer
          description: Total number of credit transactions (count, not amount)
          readOnly: true
        last_entry_date:
          type: string
          format: date-time
          nullable: true
          readOnly: true
          description: Date of most recent journal entry
        last_entry_reference:
          type: string
          readOnly: true
          description: Reference of most recent journal entry
        sub_accounts:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: List of sub-accounts if this is a parent account (empty array
            if no children)
          readOnly: true
      required:
      - account_number_mask
      - account_subtype
      - account_subtype_display
      - account_type
      - account_type_display
      - code
      - credit_balance
      - currency
      - current_balance
      - current_balance_formatted
      - debit_balance
      - description
      - has_children
      - hierarchy_level
      - iban
      - id
      - institution_name
      - is_active
      - last_entry_date
      - last_entry_reference
      - name
      - parent_account_code
      - period_balance
      - period_balance_formatted
      - sort_code
      - sub_accounts
      - total_credits
      - total_debits
    ChartOfAccountList:
      type: object
      description: Serializer for listing chart of accounts with balance information.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique account identifier
        code:
          type: string
          readOnly: true
          description: Account code from chart of accounts (e.g., '1000', '4000')
        name:
          type: string
          description: Account name from chart of accounts
          readOnly: true
        currency:
          type: string
          description: Account currency from business base currency (GBP, EUR, USD)
          readOnly: true
        account_type:
          enum:
          - asset
          - liability
          - equity
          - revenue
          - expense
          type: string
          x-spec-enum-id: bee27527493b2230
          readOnly: true
          description: |-
            Account type code (asset, liability, equity, revenue, expense)

            * `asset` - Asset
            * `liability` - Liability
            * `equity` - Equity
            * `revenue` - Revenue
            * `expense` - Expense
        account_type_display:
          type: string
          nullable: true
          description: Human-readable account type (e.g., 'Current Asset', 'Revenue')
          readOnly: true
        account_subtype:
          enum:
          - current_assets
          - non_current_assets
          - current_liabilities
          - non_current_liabilities
          - share_capital
          - share_premium
          - reserves
          - retained_earnings
          - revenue
          - other_operating_income
          - finance_income
          - direct_costs
          - operating_expenses
          - finance_costs
          - income_tax
          type: string
          x-spec-enum-id: f729e72199be4c29
          readOnly: true
          description: |-
            Account subtype code for more granular classification (bank, cash, etc.)

            * `current_assets` - Current Assets
            * `non_current_assets` - Non-current Assets
            * `current_liabilities` - Current Liabilities
            * `non_current_liabilities` - Non-current Liabilities
            * `share_capital` - Share Capital
            * `share_premium` - Share Premium
            * `reserves` - Reserves
            * `retained_earnings` - Retained Earnings
            * `revenue` - Revenue
            * `other_operating_income` - Other Operating Income
            * `finance_income` - Finance Income
            * `direct_costs` - Direct Costs
            * `operating_expenses` - Operating Expenses
            * `finance_costs` - Finance Costs
            * `income_tax` - Income Tax
        account_subtype_display:
          type: string
          nullable: true
          description: Account subtype for more granular classification
          readOnly: true
        parent_account_code:
          type: string
          nullable: true
          description: Parent account code if this is a sub-account (null for top-level
            accounts)
          readOnly: true
        current_balance:
          type: integer
          description: Current balance in cents
          readOnly: true
        current_balance_formatted:
          type: string
          description: Formatted balance with currency symbol (e.g., '£12,500.50')
          readOnly: true
        debit_balance:
          type: integer
          description: Debit balance in cents
          readOnly: true
        credit_balance:
          type: integer
          description: Credit balance in cents
          readOnly: true
        period_balance:
          type: integer
          description: Period balance in cents (null if no period filter applied)
          readOnly: true
        period_balance_formatted:
          type: string
          nullable: true
          description: Formatted period balance with currency symbol (null if no period
            filter)
          readOnly: true
        has_children:
          type: boolean
          description: Whether this account has sub-accounts (nested hierarchy)
          readOnly: true
        hierarchy_level:
          type: integer
          description: Depth in account hierarchy (0 for root accounts)
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
          description: Whether this account is active and accepting transactions
      required:
      - account_subtype
      - account_subtype_display
      - account_type
      - account_type_display
      - code
      - credit_balance
      - currency
      - current_balance
      - current_balance_formatted
      - debit_balance
      - has_children
      - hierarchy_level
      - id
      - is_active
      - name
      - parent_account_code
      - period_balance
      - period_balance_formatted
    CheckDetail:
      type: object
      description: Serializer for individual check details in checklist
      properties:
        name:
          type: string
        category:
          type: string
        status:
          type: string
        message:
          type: string
        details: {}
      required:
      - category
      - details
      - message
      - name
      - status
    ChildAccountCreateAPIRequest:
      type: object
      description: |-
        Simplified serializer for creating child accounts.

        Inherits from parent:
        - account_type
        - account_subtype
        - balance_behavior

        Only code is required; inherits accounting properties from parent.
      properties:
        code:
          type: string
          minLength: 1
          description: Unique account code within business
          maxLength: 50
        name:
          type: string
          description: Account display name
          maxLength: 255
        description:
          type: string
        external_id:
          type: string
          description: External system identifier for idempotency
          maxLength: 100
        custom_fields: {}
        institution_name:
          type: string
          maxLength: 255
        iban:
          type: string
          maxLength: 34
        sort_code:
          type: string
          maxLength: 8
        account_number_mask:
          type: string
          maxLength: 20
      required:
      - code
    Counterparty:
      type: object
      description: Serializer for counterparty (customer or vendor) in responses.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        type:
          type: string
          readOnly: true
          description: '''customer'' or ''vendor'''
        display_name:
          type: string
          readOnly: true
        external_id:
          type: string
          readOnly: true
          nullable: true
      required:
      - display_name
      - external_id
      - id
      - type
    CreateBusinessRequest:
      type: object
      description: Serializer for creating new businesses
      properties:
        external_id:
          type: string
          minLength: 1
          description: Your unique identifier for this business (used for idempotency)
          maxLength: 255
        legal_name:
          type: string
          minLength: 1
          description: Legal registered name of the business
          maxLength: 255
        entity_type:
          type: string
          minLength: 1
          description: Business entity type (e.g., 'limited', 'gmbh', 'bv'). Validated
            for GB, DE, NL, ES, BE. Any string accepted for other countries.
        phone_number:
          type: string
          description: Business phone number
        tin:
          type: string
          description: Tax identification number (other than VAT)
        vat_number:
          type: string
          description: EU VAT registration number
          maxLength: 20
        company_number:
          type: string
          description: Company registration number (e.g., Companies House number for
            UK)
          maxLength: 20
        country:
          type: string
          minLength: 1
          default: GB
          description: ISO 3166-1 alpha-2 country code (e.g., GB, DE, NL, ES, MY,
            SG)
          maxLength: 2
        province:
          type: string
          description: Province or state within the country
          maxLength: 100
        eu_nace_industry_code:
          type: string
          description: European NACE industry classification code
          maxLength: 10
        email:
          type: string
          format: email
          minLength: 1
          description: Primary email address for the business
        base_currency:
          type: string
          minLength: 1
          default: GBP
          description: 'Base currency for accounting (ISO 4217 code: EUR, GBP, USD,
            SEK, NOK, DKK, ISK, MYR, SGD)'
          maxLength: 3
        accounting_method:
          enum:
          - cash
          - accrual
          type: string
          x-spec-enum-id: 6f6d0e718e73bb81
          default: accrual
          description: |-
            Accounting method: 'cash' or 'accrual' (default: accrual)

            * `cash` - Cash Basis
            * `accrual` - Accrual Basis
        fiscal_year_end:
          type: string
          format: date
          description: 'Fiscal year end date (format: YYYY-MM-DD, e.g., ''2024-03-31''
            for March 31st year-end)'
        metadata:
          description: Custom JSON metadata for partner-specific data
      required:
      - email
      - entity_type
      - external_id
      - legal_name
    CreateCustomerCreditRequest:
      type: object
      description: |-
        Customer credit creation serializer with line_items support.

        Creates customer credits with line_items for flexible account allocation.
      properties:
        external_id:
          type: string
          minLength: 1
          description: External system identifier for this customer credit
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/CustomerCreditLineItemRequest'
          description: Array of line items for this customer credit
        customer_id:
          type: string
          format: uuid
          description: Existing customer ID to assign credit to
        customer_external_id:
          type: string
          description: External customer ID. Will create customer if not found
        source_invoice_id:
          type: string
          format: uuid
          nullable: true
          description: Optional invoice ID this credit note was created from (origin
            tracking, not allocation)
        sent_at:
          type: string
          format: date-time
          description: When the credit was sent (ISO 8601 format). Defaults to now
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/CustomerCreditAllocationRequest'
          description: Array of invoice allocations for this credit
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Transaction tags for the credit
        document:
          allOf:
          - $ref: '#/components/schemas/CustomerCreditDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
      required:
      - external_id
      - line_items
    CreateCustomerRequest:
      type: object
      description: Serializer for creating new customers
      properties:
        external_id:
          type: string
          description: Your unique identifier for this customer (used for idempotency)
        reference_number:
          type: string
          description: Customer reference number for invoices and statements
        individual_name:
          type: string
          description: Individual/contact person name (required if company_name not
            provided)
        company_name:
          type: string
          description: Registered company name (required if individual_name not provided)
        email:
          type: string
          format: email
          description: Primary email address for the customer
        mobile_phone:
          type: string
          description: Mobile phone number
        office_phone:
          type: string
          description: Office/landline phone number
        address_line1:
          type: string
          description: Street address line 1
        address_line2:
          type: string
          description: Street address line 2 (building, suite, etc.)
        city:
          type: string
          description: City or town
        state_county:
          type: string
          description: State, county, or region
        postal_code:
          type: string
          description: Postal/ZIP code
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code
        vat_number:
          type: string
          description: 'VAT registration number (for UK: GB followed by 9 digits)'
        tax_exempt:
          type: boolean
          default: false
          description: Whether customer is exempt from tax/VAT
        status:
          enum:
          - active
          - archived
          - suspended
          type: string
          description: |-
            * `active` - Active
            * `archived` - Archived
            * `suspended` - Suspended
          x-spec-enum-id: 8c91d15064e148c5
        transaction_tags:
          type: array
          items: {}
          description: Array of tags for categorization and filtering
        notes:
          type: string
          description: Internal notes about the customer
        metadata:
          description: Custom JSON metadata for partner-specific data
        payment_terms_days:
          type: integer
          description: Number of days for payment terms (e.g., 30 for Net 30)
        credit_limit_cents:
          type: integer
          minimum: 0
          description: Maximum credit limit in cents (e.g., 100000 for £1,000)
        document:
          allOf:
          - $ref: '#/components/schemas/CustomerDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    CreateRefundPaymentRequestRequest:
      type: object
      description: Serializer for creating a refund payment (reusable for other endpoints).
        All amounts in cents.
      properties:
        amount_cents:
          type: integer
          minimum: 1
          description: Amount to disburse for this refund in cents (e.g., 20000 for
            €200.00)
        method:
          enum:
          - CASH
          - CHECK
          - CREDIT_CARD
          - DEBIT_CARD
          - ACH
          - BANK_TRANSFER
          - PAYPAL
          - STRIPE
          - OTHER
          type: string
          x-spec-enum-id: c331bf4f48370b25
          description: |-
            Payment method for the refund payment

            * `CASH` - Cash
            * `CHECK` - Check
            * `CREDIT_CARD` - Credit Card
            * `DEBIT_CARD` - Debit Card
            * `ACH` - ACH
            * `BANK_TRANSFER` - Bank Transfer
            * `PAYPAL` - PayPal
            * `STRIPE` - Stripe
            * `OTHER` - Other
        completed_at:
          type: string
          format: date-time
          description: When the refund payment was completed
        external_id:
          type: string
          minLength: 1
          description: Required idempotency key per refund (unique within a refund)
          maxLength: 255
        processor:
          type: string
          description: Payment processor
          maxLength: 100
        memo:
          type: string
          description: Optional notes for the payment
        transaction_tags:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 100
          description: Optional list of string tags for reconciliation
        refund_processing_fee_cents:
          type: integer
          minimum: 0
          default: 0
          description: Processing fee for this refund payment in cents (e.g., 30 for
            €0.30)
      required:
      - amount_cents
      - external_id
      - method
    CreateSimpleRefundRequest:
      type: object
      description: Serializer for creating simple refunds
      properties:
        invoice_id:
          type: string
          format: uuid
          description: Invoice to refund
        method:
          enum:
          - CASH
          - CHECK
          - CREDIT_CARD
          - DEBIT_CARD
          - ACH
          - BANK_TRANSFER
          - PAYPAL
          - STRIPE
          - OTHER
          type: string
          x-spec-enum-id: c331bf4f48370b25
          description: |-
            Payment method for the refund

            * `CASH` - Cash
            * `CHECK` - Check
            * `CREDIT_CARD` - Credit Card
            * `DEBIT_CARD` - Debit Card
            * `ACH` - ACH
            * `BANK_TRANSFER` - Bank Transfer
            * `PAYPAL` - PayPal
            * `STRIPE` - Stripe
            * `OTHER` - Other
        completed_at:
          type: string
          format: date-time
          description: When the refund was completed
        amount_cents:
          type: integer
          minimum: 1
          description: 'Optional: Partial refund amount in cents. If not provided,
            refunds full amount.'
        external_id:
          type: string
          minLength: 1
          description: Required external identifier for idempotency (unique per business)
          maxLength: 255
        memo:
          type: string
          minLength: 1
          description: Optional description
        reference_number:
          type: string
          minLength: 1
          description: Optional reference number
          maxLength: 100
        processor:
          type: string
          minLength: 1
          description: Payment processor (e.g., STRIPE)
          maxLength: 100
        refund_processing_fee_cents:
          type: integer
          minimum: 0
          default: 0
          description: Processing fee for the refund in cents
        document:
          allOf:
          - $ref: '#/components/schemas/RefundDocumentUploadRequest'
          writeOnly: true
      required:
      - completed_at
      - external_id
      - invoice_id
      - method
    CreateVendorCreditRequest:
      type: object
      description: |-
        Vendor credit creation serializer with line_items support.

        Creates vendor credits with line_items for flexible account allocation.
      properties:
        external_id:
          type: string
          minLength: 1
          description: External system identifier for this vendor credit
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/VendorCreditLineItemRequest'
          description: Array of line items for this vendor credit
        vendor_id:
          type: string
          format: uuid
          description: Existing vendor ID to assign credit to
        vendor_external_id:
          type: string
          description: External vendor ID. Will create vendor if not found
        source_bill_id:
          type: string
          format: uuid
          nullable: true
          description: Optional bill ID this credit note was created from (origin
            tracking, not allocation)
        received_at:
          type: string
          format: date-time
          description: When the credit was received (ISO 8601). Defaults to now if
            provided
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/VendorCreditAllocationRequest'
          description: Array of bill allocations for this credit
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Transaction tags for the credit
        document:
          allOf:
          - $ref: '#/components/schemas/VendorCreditDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
      required:
      - external_id
      - line_items
    CreateVendorRefundAllocationRequest:
      type: object
      description: Serializer for creating vendor refund allocations. All amounts
        in cents.
      properties:
        allocation_type:
          enum:
          - bill
          - payment
          - credit
          type: string
          x-spec-enum-id: 22d8aab8e694331c
          description: |-
            Type of allocation: 'bill' (apply to bill), 'payment' (refund payment), or 'credit' (credit balance)

            * `bill` - bill
            * `payment` - payment
            * `credit` - credit
        amount_cents:
          type: integer
          minimum: 1
          description: Allocation amount in cents (e.g., 10050 for €100.50)
        bill_id:
          type: string
          format: uuid
          nullable: true
          description: Bill ID if allocation_type is 'bill'
        bill_payment_id:
          type: string
          format: uuid
          nullable: true
          description: Bill payment ID if allocation_type is 'payment'
        description:
          type: string
          description: Allocation description or notes
          maxLength: 500
        metadata:
          nullable: true
          description: Custom key-value pairs for this allocation
      required:
      - allocation_type
      - amount_cents
    CreateVendorRefundPaymentRequest:
      type: object
      description: Serializer for creating vendor refund payments. All amounts in
        cents.
      properties:
        payment_reference:
          type: string
          description: Your internal payment reference or tracking number
          maxLength: 100
        refunded_amount_cents:
          type: integer
          minimum: 1
          description: Refunded amount in cents
        processing_fee_cents:
          type: integer
          minimum: 0
          default: 0
          description: Processing fee in cents
        payment_method:
          enum:
          - bank_transfer
          - ach
          - wire
          - check
          - credit_card
          - cash
          - other
          type: string
          x-spec-enum-id: e41885a675157233
          default: bank_transfer
          description: |-
            Payment method: bank_transfer, ach, wire, check, credit_card, cash, other

            * `bank_transfer` - bank_transfer
            * `ach` - ach
            * `wire` - wire
            * `check` - check
            * `credit_card` - credit_card
            * `cash` - cash
            * `other` - other
        processor:
          enum:
          - stripe
          - wise
          - paypal
          - bank_transfer
          - internal
          type: string
          x-spec-enum-id: d29afebe022918d2
          default: bank_transfer
          description: |-
            Payment processor: stripe, wise, paypal, bank_transfer, internal

            * `stripe` - stripe
            * `wise` - wise
            * `paypal` - paypal
            * `bank_transfer` - bank_transfer
            * `internal` - internal
        payment_date:
          type: string
          format: date
          description: 'Date when payment was made (ISO date: YYYY-MM-DD)'
        description:
          type: string
          description: Payment description or context
        memo:
          type: string
          description: Internal memo or notes
        metadata:
          nullable: true
          description: Custom key-value pairs for payment context
      required:
      - refunded_amount_cents
    CreateVendorRefundRequest:
      type: object
      description: |-
        Serializer for creating vendor refunds.
        Handles validation and conversion of amounts from base units to cents.
      properties:
        vendor_id:
          type: string
          format: uuid
          description: Vendor UUID
        external_id:
          type: string
          description: External/partner refund ID for idempotency
          maxLength: 255
        refund_type:
          enum:
          - overpayment
          - credit_balance
          - duplicate_payment
          - billing_error
          - goods_return
          - service_cancellation
          - other
          type: string
          x-spec-enum-id: cc2aba03e62727c0
          default: overpayment
          description: |-
            Type/reason for the refund

            * `overpayment` - overpayment
            * `credit_balance` - credit_balance
            * `duplicate_payment` - duplicate_payment
            * `billing_error` - billing_error
            * `goods_return` - goods_return
            * `service_cancellation` - service_cancellation
            * `other` - other
        reference_number:
          type: string
          description: External reference number
          maxLength: 100
        total_refunded_amount_cents:
          type: integer
          minimum: 1
          description: Total refunded amount in cents (e.g., 10050 for €100.50)
        currency:
          enum:
          - EUR
          - GBP
          - USD
          type: string
          x-spec-enum-id: 9b3a5a872ad0ed07
          default: EUR
          description: |-
            ISO 4217 currency code

            * `EUR` - EUR
            * `GBP` - GBP
            * `USD` - USD
        refund_date:
          type: string
          format: date
          description: 'Date when refund was issued (ISO date: YYYY-MM-DD)'
        description:
          type: string
          description: Description of the refund reason or context
        memo:
          type: string
          description: Internal memo or notes about this refund
        reason:
          type: string
          description: Detailed explanation for the refund (max 500 characters)
          maxLength: 500
        metadata:
          nullable: true
          description: Custom key-value pairs for additional refund context (max 10kb)
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/CreateVendorRefundAllocationRequest'
          nullable: true
        payments:
          type: array
          items:
            $ref: '#/components/schemas/CreateVendorRefundPaymentRequest'
          nullable: true
        document:
          allOf:
          - $ref: '#/components/schemas/VendorRefundDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
      required:
      - total_refunded_amount_cents
      - vendor_id
    CreateVendorRequest:
      type: object
      description: Input serializer for creating a vendor
      properties:
        external_id:
          type: string
          description: Your unique identifier for this vendor (used for idempotency)
        individual_name:
          type: string
          description: Vendor individual name (required if company_name not provided)
        company_name:
          type: string
          description: Registered company name (required if individual_name not provided)
        email:
          type: string
          format: email
          description: Primary email address for vendor communications
        mobile_phone:
          type: string
          description: Mobile phone number (E.164 format recommended, e.g., +44 7700
            900123)
        office_phone:
          type: string
          description: Office phone number (E.164 format recommended, e.g., +44 20
            7946 0958)
        address_string:
          type: string
          description: Vendor mailing address (single string)
        memo:
          type: string
          description: Internal notes or description for this vendor
        transaction_tags:
          type: array
          items: {}
          description: List of tags for categorization
        country:
          type: string
          description: Two-letter country code (ISO 3166-1 alpha-2, e.g., NL, DE,
            US)
          maxLength: 2
        vat_number:
          type: string
          description: VAT/Tax registration number (e.g., NL123456789B01 for Netherlands)
        document:
          allOf:
          - $ref: '#/components/schemas/VendorDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    CreditNoteStats:
      type: object
      description: Statistics for customer credit notes.
      properties:
        all:
          type: integer
          description: Total number of credit notes
        draft:
          type: integer
          description: Number of unapplied credit notes (draft, sent, partially_applied)
        applied:
          type: integer
          description: Number of fully applied credit notes
      required:
      - all
      - applied
      - draft
    Customer:
      type: object
      description: |-
        Main customer serializer for customer API endpoints
        Returns customer information with comprehensive details
        Used for both list and detail responses
      properties:
        type:
          type: string
          description: Type identifier (always 'CustomerData')
          readOnly: true
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique identifier for the customer
        external_id:
          type: string
          description: Your unique identifier for this customer (used for idempotency)
        reference_number:
          type: string
          description: Customer reference number for invoices and statements
        individual_name:
          type: string
          description: Individual/contact person name (required if company_name not
            provided)
        company_name:
          type: string
          description: Registered company name (required if individual_name not provided)
        display_name:
          type: string
          readOnly: true
          description: Display name for the customer (auto-generated from company_name
            or individual_name)
        email:
          type: string
          format: email
          description: Primary email address for the customer
        mobile_phone:
          type: string
          description: Mobile phone number
        office_phone:
          type: string
          description: Office/landline phone number
        address_line1:
          type: string
          description: Street address line 1
        address_line2:
          type: string
          description: Street address line 2 (building, suite, etc.)
        city:
          type: string
          description: City or town
        state_county:
          type: string
          description: State, county, or region
        postal_code:
          type: string
          description: Postal/ZIP code
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code
        full_address:
          type: string
          readOnly: true
          description: Complete formatted address with all fields
        address_string:
          type: string
          readOnly: true
          description: Single-line formatted address
        vat_number:
          type: string
          description: 'VAT registration number (for UK: GB followed by 9 digits)'
        tax_exempt:
          type: boolean
          description: Whether customer is exempt from tax/VAT
        status:
          type: string
          description: Customer status (ACTIVE or ARCHIVED)
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
          description: Whether the customer is active (read-only)
        is_archived:
          type: boolean
          readOnly: true
          description: Whether the customer is archived (read-only)
        transaction_tags:
          type: array
          items: {}
          description: Array of tags for categorization and filtering
        notes:
          type: string
          description: Internal notes about the customer
        metadata:
          description: Custom JSON metadata for partner-specific data
        payment_terms_days:
          type: integer
          description: Number of days for payment terms (e.g., 30 for Net 30)
        credit_limit:
          type: integer
          description: Maximum credit limit in cents (e.g., 100000 for £1,000)
          readOnly: true
        credit_limit_cents:
          type: integer
          description: Maximum credit limit in cents (e.g., 100000 for £1,000)
        outstanding_balance:
          type: integer
          description: Current outstanding balance in cents (read-only, computed)
          readOnly: true
        documents:
          type: array
          items:
            $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: All documents linked to this customer with presigned URLs (retrieve
            only, not in list)
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the customer was created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the customer was last updated
        archived_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the customer was archived (null if active)
      required:
      - address_line1
      - address_line2
      - address_string
      - archived_at
      - city
      - company_name
      - country
      - created_at
      - credit_limit
      - credit_limit_cents
      - display_name
      - documents
      - email
      - external_id
      - full_address
      - id
      - individual_name
      - is_active
      - is_archived
      - metadata
      - mobile_phone
      - notes
      - office_phone
      - outstanding_balance
      - payment_terms_days
      - postal_code
      - reference_number
      - state_county
      - status
      - tax_exempt
      - transaction_tags
      - type
      - updated_at
      - vat_number
    CustomerAging:
      type: object
      description: |-
        AR aging for a single customer.

        Includes:
        - Customer identification
        - Total outstanding amount
        - Breakdown by aging bucket
      properties:
        customer_id:
          type: string
          format: uuid
          description: Customer UUID
        customer_name:
          type: string
          description: Customer name (company_name or individual_name)
        total_outstanding_cents:
          type: integer
          description: Total outstanding amount for this customer in cents
        aging_buckets:
          allOf:
          - $ref: '#/components/schemas/ARAgingBuckets'
          description: Outstanding amount by aging bucket
      required:
      - aging_buckets
      - customer_id
      - customer_name
      - total_outstanding_cents
    CustomerCredit:
      type: object
      description: Customer credit serializer for API responses.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique customer credit identifier
        external_id:
          type: string
          description: Your external system identifier for this credit
          maxLength: 255
        status:
          enum:
          - draft
          - sent
          - applied
          - partially_applied
          - void
          type: string
          description: 'Credit status: draft, sent, partially_applied, applied, void
            (computed from allocations)'
          readOnly: true
        sent_at:
          type: string
          format: date-time
          readOnly: true
          description: When the credit was sent
        customer:
          type: object
          additionalProperties: {}
          description: Customer receiving this credit (inline details)
          readOnly: true
        source_invoice_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: Invoice ID this credit was created from (origin tracking, not
            allocation)
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/CustomerCreditLineItemResponse'
          readOnly: true
          description: Array of credit line items
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/CustomerCreditInvoiceAllocationResponse'
          readOnly: true
          description: Array of invoice allocations
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Transaction tags for the credit
          readOnly: true
        total_amount:
          type: integer
          description: Total credit amount in cents
          readOnly: true
        applied_amount:
          type: integer
          description: Applied credit amount in cents
          readOnly: true
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          x-spec-enum-id: 7e6a70e4775b3009
          description: |-
            Credit currency (e.g., GBP, EUR, USD)

            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
        document:
          allOf:
          - $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: Latest document linked to this customer credit
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Credit creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
      required:
      - allocations
      - applied_amount
      - created_at
      - customer
      - document
      - id
      - line_items
      - sent_at
      - source_invoice_id
      - status
      - tags
      - total_amount
      - updated_at
    CustomerCreditAllocationRequest:
      type: object
      description: Serializer for customer credit allocations to invoices.
      properties:
        amount:
          type: integer
          minimum: 1
          description: Amount to allocate to invoice in cents
        invoice_id:
          type: string
          format: uuid
          description: Invoice ID to allocate credit to
      required:
      - amount
      - invoice_id
    CustomerCreditAllocationSummary:
      type: object
      description: Credit allocation summary for invoice detail view - shows credits
        applied to this invoice.
      properties:
        amount_cents:
          type: integer
        applied_at:
          type: string
          format: date-time
        credit_note_id:
          type: string
          format: uuid
        reference_number:
          type: string
      required:
      - amount_cents
      - applied_at
      - credit_note_id
    CustomerCreditDocumentUploadRequest:
      type: object
      description: Customer credit specific document upload payload.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: customer_credit
        upload_source:
          type: string
        metadata: {}
        tags: {}
    CustomerCreditInvoiceAllocationResponse:
      type: object
      description: Response serializer for customer credit allocations to invoices
        (for OpenAPI documentation).
      properties:
        invoice_id:
          type: string
          format: uuid
          description: UUID of the invoice this credit is allocated to
        invoice_number:
          type: string
          description: Invoice number (e.g., INV-00019)
        amount_cents:
          type: integer
          description: Amount allocated to this invoice in cents
        invoice_outstanding_balance_cents:
          type: integer
          description: Current outstanding balance on the invoice in cents (after
            all allocations)
        applied_at:
          type: string
          format: date-time
          description: When the allocation was applied
      required:
      - amount_cents
      - applied_at
      - invoice_id
      - invoice_number
      - invoice_outstanding_balance_cents
    CustomerCreditLineItemRequest:
      type: object
      description: Serializer for customer credit line items.
      properties:
        amount:
          type: integer
          minimum: 1
          description: NET credit amount in cents (BEFORE taxes) for this line item
        tax_amount_cents:
          type: integer
          minimum: 0
          description: Tax amount in cents (e.g., VAT). Required field.
        revenue_account_identifier:
          nullable: true
          description: Account identifier for revenue posting (optional)
        memo:
          type: string
          description: Line item memo/description
        metadata:
          type: object
          additionalProperties: {}
          description: Line item metadata (max 10kb)
        reference_number:
          type: string
          description: Line item reference number
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Line item transaction tags
      required:
      - amount
      - tax_amount_cents
    CustomerCreditLineItemResponse:
      type: object
      description: Serializer for customer credit line items in API responses.
      properties:
        amount:
          type: integer
          description: Credit amount in cents
          readOnly: true
        revenue_account_identifier:
          allOf:
          - $ref: '#/components/schemas/AccountIdentifier'
          nullable: true
          readOnly: true
          description: Account identifier for revenue posting
        memo:
          type: string
        metadata: {}
        tags:
          type: array
          items:
            type: string
          description: Line item transaction tags
          readOnly: true
      required:
      - amount
      - revenue_account_identifier
      - tags
    CustomerCreditLineItemResponseRequest:
      type: object
      description: Serializer for customer credit line items in API responses.
      properties:
        memo:
          type: string
        metadata: {}
    CustomerCreditRequest:
      type: object
      description: Customer credit serializer for API responses.
      properties:
        external_id:
          type: string
          description: Your external system identifier for this credit
          maxLength: 255
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          x-spec-enum-id: 7e6a70e4775b3009
          description: |-
            Credit currency (e.g., GBP, EUR, USD)

            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
    CustomerDocumentUploadRequest:
      type: object
      description: Customer specific document upload payload.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: customer_document
        upload_source:
          type: string
        metadata: {}
        tags: {}
    CustomerEmbedded:
      type: object
      description: Customer details embedded in payment and other response objects.
      properties:
        id:
          type: string
          format: uuid
          description: Customer UUID
        name:
          type: string
          description: Customer display name
        email:
          type: string
          format: email
          description: Customer email address
        company_name:
          type: string
          description: Company name
      required:
      - company_name
      - email
      - id
      - name
    CustomerRequest:
      type: object
      description: |-
        Main customer serializer for customer API endpoints
        Returns customer information with comprehensive details
        Used for both list and detail responses
      properties:
        external_id:
          type: string
          minLength: 1
          description: Your unique identifier for this customer (used for idempotency)
        reference_number:
          type: string
          minLength: 1
          description: Customer reference number for invoices and statements
        individual_name:
          type: string
          minLength: 1
          description: Individual/contact person name (required if company_name not
            provided)
        company_name:
          type: string
          minLength: 1
          description: Registered company name (required if individual_name not provided)
        email:
          type: string
          format: email
          minLength: 1
          description: Primary email address for the customer
        mobile_phone:
          type: string
          minLength: 1
          description: Mobile phone number
        office_phone:
          type: string
          minLength: 1
          description: Office/landline phone number
        address_line1:
          type: string
          minLength: 1
          description: Street address line 1
        address_line2:
          type: string
          minLength: 1
          description: Street address line 2 (building, suite, etc.)
        city:
          type: string
          minLength: 1
          description: City or town
        state_county:
          type: string
          minLength: 1
          description: State, county, or region
        postal_code:
          type: string
          minLength: 1
          description: Postal/ZIP code
        country:
          type: string
          minLength: 1
          description: ISO 3166-1 alpha-2 country code
        vat_number:
          type: string
          minLength: 1
          description: 'VAT registration number (for UK: GB followed by 9 digits)'
        tax_exempt:
          type: boolean
          description: Whether customer is exempt from tax/VAT
        transaction_tags:
          type: array
          items: {}
          description: Array of tags for categorization and filtering
        notes:
          type: string
          minLength: 1
          description: Internal notes about the customer
        metadata:
          description: Custom JSON metadata for partner-specific data
        payment_terms_days:
          type: integer
          description: Number of days for payment terms (e.g., 30 for Net 30)
        credit_limit_cents:
          type: integer
          description: Maximum credit limit in cents (e.g., 100000 for £1,000)
      required:
      - address_line1
      - address_line2
      - city
      - company_name
      - country
      - credit_limit_cents
      - email
      - external_id
      - individual_name
      - metadata
      - mobile_phone
      - notes
      - office_phone
      - payment_terms_days
      - postal_code
      - reference_number
      - state_county
      - tax_exempt
      - transaction_tags
      - vat_number
    DashboardBusiness:
      type: object
      description: Serializer for a business in the dashboard response.
      properties:
        business_id:
          type: string
          format: uuid
        business_name:
          type: string
        business_status:
          type: string
        assigned_services:
          type: array
          items:
            type: string
        metrics:
          $ref: '#/components/schemas/BusinessMetrics'
        assignment_info:
          $ref: '#/components/schemas/AssignmentInfo'
      required:
      - assigned_services
      - assignment_info
      - business_id
      - business_name
      - business_status
      - metrics
    DashboardPagination:
      type: object
      description: Serializer for dashboard pagination info.
      properties:
        page:
          type: integer
        page_size:
          type: integer
        total_pages:
          type: integer
        total_count:
          type: integer
      required:
      - page
      - page_size
      - total_count
      - total_pages
    DashboardResponse:
      type: object
      description: Serializer for the complete dashboard response.
      properties:
        businesses:
          type: array
          items:
            $ref: '#/components/schemas/DashboardBusiness'
        summary:
          $ref: '#/components/schemas/DashboardSummary'
        pagination:
          $ref: '#/components/schemas/DashboardPagination'
      required:
      - businesses
      - pagination
      - summary
    DashboardSummary:
      type: object
      description: Serializer for dashboard summary stats.
      properties:
        total_businesses:
          type: integer
        total_open_tasks:
          type: integer
        total_overdue_tasks:
          type: integer
      required:
      - total_businesses
      - total_open_tasks
      - total_overdue_tasks
    DepreciationEntry:
      type: object
      description: Depreciation entry serializer (read-only for API users). All amounts
        in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        asset:
          type: string
          format: uuid
          readOnly: true
        period_start_date:
          type: string
          format: date
          readOnly: true
          description: First day of depreciation period (month start)
        period_end_date:
          type: string
          format: date
          readOnly: true
          description: Last day of depreciation period (month end)
        depreciation_amount:
          type: integer
          description: Depreciation amount in cents
          readOnly: true
        depreciation_amount_cents:
          type: integer
          readOnly: true
          description: Depreciation amount for this period in cents
        period_month:
          type: string
          readOnly: true
        journal_entry:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: GL journal entry for this depreciation
        is_posted:
          type: boolean
          readOnly: true
          description: True if journal entry has been posted to GL
        posted_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        created_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - asset
      - created_at
      - depreciation_amount
      - depreciation_amount_cents
      - id
      - is_posted
      - journal_entry
      - period_end_date
      - period_month
      - period_start_date
      - posted_at
    DestinationLedgerAccountInputRequest:
      type: object
      description: Account identifier input — supports only AccountId for now.
      properties:
        type:
          enum:
          - AccountId
          type: string
          description: '* `AccountId` - AccountId'
          x-spec-enum-id: 13108aa16342a16f
        id:
          type: string
          format: uuid
      required:
      - id
      - type
    DirectSMEBusiness:
      type: object
      description: Serializer for business details in Direct SME Portal.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          maxLength: 255
        country:
          enum:
          - GB
          - DE
          - FR
          - NL
          - ES
          - IT
          - IE
          - BE
          - AT
          - PT
          - SE
          - 'NO'
          - DK
          - FI
          - IS
          - MY
          - SG
          type: string
          description: |-
            * `GB` - United Kingdom
            * `DE` - Germany
            * `FR` - France
            * `NL` - Netherlands
            * `ES` - Spain
            * `IT` - Italy
            * `IE` - Ireland
            * `BE` - Belgium
            * `AT` - Austria
            * `PT` - Portugal
            * `SE` - Sweden
            * `NO` - Norway
            * `DK` - Denmark
            * `FI` - Finland
            * `IS` - Iceland
            * `MY` - Malaysia
            * `SG` - Singapore
          x-spec-enum-id: f4d5c691ea686889
        base_currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
        email:
          type: string
          format: email
          maxLength: 254
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - email
      - id
      - name
      - updated_at
    DirectSMEBusinessCreateAPIRequest:
      type: object
      description: Serializer for creating a business.
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        country:
          type: string
          minLength: 1
          maxLength: 2
        base_currency:
          type: string
          minLength: 1
          default: EUR
          maxLength: 3
        email:
          type: string
          format: email
      required:
      - country
      - name
    DirectSMEBusinessTokenResponse:
      type: object
      description: Serializer for business token response in Direct SME Portal.
      properties:
        access_token:
          type: string
          description: JWT access token for SDK
        expires_in:
          type: integer
          description: Token expiry in seconds
        token_type:
          type: string
          description: Token type (Bearer)
        business_id:
          type: string
          format: uuid
          description: Business ID the token is scoped to
      required:
      - access_token
      - business_id
      - expires_in
      - token_type
    DirectSMEBusinessTokenResponseRequest:
      type: object
      description: Serializer for business token response in Direct SME Portal.
      properties:
        access_token:
          type: string
          minLength: 1
          description: JWT access token for SDK
        expires_in:
          type: integer
          description: Token expiry in seconds
        token_type:
          type: string
          minLength: 1
          description: Token type (Bearer)
        business_id:
          type: string
          format: uuid
          description: Business ID the token is scoped to
      required:
      - access_token
      - business_id
      - expires_in
      - token_type
    DisposalHistoryRequest:
      type: object
      description: Validate disposal_history endpoint input.
      properties:
        parameters:
          type: object
          additionalProperties: {}
    DocumentFileUrl:
      type: object
      description: Serializer for document file URL with metadata.
      properties:
        url:
          type: string
          format: uri
          description: Presigned URL for document download
        expires_in:
          type: integer
          description: Seconds until URL expires
        document_id:
          type: string
          format: uuid
          description: Document UUID
        file_name:
          type: string
          description: Original document filename
        file_size:
          type: integer
          description: File size in bytes
        mime_type:
          type: string
          description: MIME type of the document
      required:
      - document_id
      - expires_in
      - file_name
      - file_size
      - mime_type
      - url
    EntityReconciliationDetail:
      type: object
      description: Which bank transaction an entity (invoice/bill payment) is reconciled
        to.
      properties:
        payment_type:
          type: string
        bank_transaction_id:
          type: string
          format: uuid
        bank_transaction_date:
          type: string
          format: date-time
        bank_transaction_amount_cents:
          type: integer
        bank_transaction_direction:
          type: string
        reconciled_amount_cents:
          type: integer
        reconciliation_link_id:
          type: string
          format: uuid
        reconciled_at:
          type: string
          format: date-time
        currency:
          type: string
        bank_account_name:
          type: string
        notes:
          type: string
      required:
      - bank_transaction_amount_cents
      - bank_transaction_date
      - bank_transaction_direction
      - bank_transaction_id
      - currency
      - reconciled_amount_cents
      - reconciled_at
      - reconciliation_link_id
    ErrorResponse:
      type: object
      description: Standard error response format
      properties:
        error_code:
          type: string
          description: Error code for programmatic handling
        message:
          type: string
          nullable: true
          description: Human-readable error message
        detail:
          type: object
          additionalProperties: {}
          description: Additional error details including field_errors and debug info
        request_id:
          type: string
          description: Request ID for tracing
      required:
      - error_code
      - message
    ExpenseAccount:
      type: object
      description: |-
        Individual GL account within an expense category.

        Represents a single Account with its period total.
      properties:
        account_id:
          type: string
          format: uuid
          description: Account UUID
        account_code:
          type: string
          description: Account code
        account_name:
          type: string
          description: Account name
        amount_cents:
          type: integer
          description: Total amount for this account in cents
      required:
      - account_code
      - account_id
      - account_name
      - amount_cents
    ExpenseBreakdown:
      type: object
      description: |-
        Complete expense breakdown response.

        Includes:
        - Business and period metadata
        - Total expenses across all categories
        - Category-by-category breakdown with percentages (sorted by amount descending)
      properties:
        business_id:
          type: string
          format: uuid
          description: Business UUID
        start_date:
          type: string
          format: date
          description: Report period start
        end_date:
          type: string
          format: date
          description: Report period end
        currency:
          type: string
          description: Business base currency (e.g., EUR, GBP, USD)
        total_expenses_cents:
          type: integer
          description: Total expenses across all categories in cents
        categories:
          type: array
          items:
            $ref: '#/components/schemas/ExpenseCategory'
          description: Expense categories (sorted by amount descending)
      required:
      - business_id
      - categories
      - currency
      - end_date
      - start_date
      - total_expenses_cents
    ExpenseCategory:
      type: object
      description: |-
        Expense category (account subtype) with percentage and line items.

        Categories:
        - direct_costs: Cost of Goods Sold
        - operating_expenses: Operating Expenses
        - finance_costs: Finance Costs (interest, bank fees)
        - income_tax: Income Tax

        Each category includes:
        - Total amount
        - Percentage of total expenses
        - Individual GL accounts (sorted by amount descending)
      properties:
        category:
          type: string
          description: Category key (e.g., 'operating_expenses')
        display_name:
          type: string
          description: Human-readable category name (e.g., 'Operating Expenses')
        total_cents:
          type: integer
          description: Total amount for this category in cents
        percentage:
          type: number
          format: double
          description: Percentage of total expenses (0-100)
        accounts:
          type: array
          items:
            $ref: '#/components/schemas/ExpenseAccount'
          description: Individual GL accounts within this category (sorted by amount
            descending)
      required:
      - accounts
      - category
      - display_name
      - percentage
      - total_cents
    FileLink:
      type: object
      description: |-
        Serializer for file link metadata in linked documents.

        Contains presigned S3 URL and document metadata for direct file access.
        URLs are temporary and expire after the specified duration.
      properties:
        url:
          type: string
          format: uri
          description: Presigned S3 URL for direct document download. Temporary and
            expires after expires_in seconds.
        expires_in:
          type: integer
          description: Seconds until the URL expires (typically 3600 for normal docs,
            1800 for sensitive)
        document_id:
          type: string
          format: uuid
          description: Unique identifier of the document
        file_name:
          type: string
          description: Original filename of the document
        file_size:
          type: integer
          description: File size in bytes
        mime_type:
          type: string
          description: MIME type of the document (e.g., 'application/pdf', 'image/png')
      required:
      - document_id
      - expires_in
      - file_name
      - file_size
      - mime_type
      - url
    FinancialBusinessDetail:
      type: object
      description: |-
        Detailed business serializer for financial portal
        Inherits from Platform API BusinessSerializer for consistency
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique identifier for the business
        external_id:
          type: string
          description: Your unique identifier for this business
        legal_name:
          type: string
          description: Legal registered name of the business
          maxLength: 255
        name:
          type: string
          description: Display name for the business (defaults to legal_name)
          maxLength: 255
        entity_type:
          type: string
          description: Business entity type (e.g., 'limited', 'gmbh', 'bv')
        phone_number:
          type: string
          description: Business phone number
        tin:
          type: string
          description: Tax identification number (other than VAT)
        vat_number:
          type: string
          description: EU VAT registration number
        company_number:
          type: string
          description: Company registration number (e.g., Companies House number for
            UK)
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code (e.g., GB, DE, NL, MY, SG)
          maxLength: 2
        province:
          type: string
          description: Province or state within the country
          maxLength: 100
        eu_nace_industry_code:
          type: string
          description: European NACE industry classification code
          maxLength: 10
        email:
          type: string
          format: email
          description: Primary email address for the business
        base_currency:
          type: string
          description: Base currency for accounting (ISO 4217 code)
          maxLength: 3
        accounting_method:
          type: string
          description: 'Accounting method: ''cash'' or ''accrual'''
          maxLength: 20
        fiscal_year_end:
          type: string
          format: date
          description: Fiscal year end date
        activation_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was activated
        is_active:
          type: boolean
          readOnly: true
          description: Whether the business is active (false if archived)
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when the business was last updated
        metadata:
          description: Custom JSON metadata for partner-specific data
      required:
      - accounting_method
      - activation_at
      - base_currency
      - country
      - created_at
      - email
      - fiscal_year_end
      - id
      - is_active
      - legal_name
      - updated_at
    FinancialBusinessList:
      type: object
      description: Serializer for listing businesses assigned to financial admin
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        legal_name:
          type: string
          readOnly: true
        external_id:
          type: string
          readOnly: true
        email:
          type: string
          format: email
          readOnly: true
        country:
          enum:
          - GB
          - DE
          - FR
          - NL
          - ES
          - IT
          - IE
          - BE
          - AT
          - PT
          - SE
          - 'NO'
          - DK
          - FI
          - IS
          - MY
          - SG
          type: string
          description: |-
            * `GB` - United Kingdom
            * `DE` - Germany
            * `FR` - France
            * `NL` - Netherlands
            * `ES` - Spain
            * `IT` - Italy
            * `IE` - Ireland
            * `BE` - Belgium
            * `AT` - Austria
            * `PT` - Portugal
            * `SE` - Sweden
            * `NO` - Norway
            * `DK` - Denmark
            * `FI` - Finland
            * `IS` - Iceland
            * `MY` - Malaysia
            * `SG` - Singapore
          x-spec-enum-id: f4d5c691ea686889
          readOnly: true
        base_currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        assignment_details:
          type: object
          additionalProperties: {}
          nullable: true
          description: |-
            Get assignment details for this business.

            N+1 Prevention: Uses prefetched `firm_assignment_list` attribute
            instead of querying the database for each business.

            The Prefetch in BusinessListView filters by:
            - financial_admin_partner (the admin's firm)
            - is_active=True
            This guarantees at most one assignment per business in the list.
            If no assignment exists (edge case: became inactive between query and
            serialization), we safely return None.
          readOnly: true
      required:
      - assignment_details
      - base_currency
      - country
      - created_at
      - email
      - external_id
      - id
      - is_active
      - legal_name
      - name
      - updated_at
    FinancialDocument:
      type: object
      description: |-
        Main serializer for FinancialDocument list/retrieve responses.

        Provides a unified view of all document types (AR, AP, GENERIC).
      properties:
        type:
          type: string
          readOnly: true
          description: Always 'FinancialDocumentData' for type discrimination
        id:
          type: string
          format: uuid
          readOnly: true
        business_id:
          type: string
          format: uuid
          readOnly: true
        external_id:
          type: string
          readOnly: true
          nullable: true
        workflow_type:
          type: string
          readOnly: true
          description: 'Workflow type: AR, AP, or GENERIC'
        document_type:
          type: string
          readOnly: true
          description: 'Document type: sales_invoice, bill, credit_note, etc.'
        status:
          type: string
          readOnly: true
          description: Document status
        counterparty:
          allOf:
          - $ref: '#/components/schemas/Counterparty'
          nullable: true
          readOnly: true
          description: Customer (AR) or Vendor (AP) details
        reference_number:
          type: string
          readOnly: true
          nullable: true
        reference_date:
          type: string
          format: date
          readOnly: true
          nullable: true
        due_date:
          type: string
          format: date
          readOnly: true
          nullable: true
        payment_terms:
          type: string
          readOnly: true
          nullable: true
        currency:
          type: string
          readOnly: true
          nullable: true
        subtotal:
          type: integer
          readOnly: true
          description: Subtotal in cents
        tax_amount:
          type: integer
          readOnly: true
          description: Tax amount in cents
        total_amount:
          type: integer
          readOnly: true
          description: Total amount in cents
        amount_paid:
          type: integer
          readOnly: true
          description: Amount paid in cents
        amount_due:
          type: integer
          readOnly: true
          description: Amount due in cents
        is_overdue:
          type: boolean
          readOnly: true
        is_fully_paid:
          type: boolean
          readOnly: true
        needs_review:
          type: boolean
          readOnly: true
        review_reasons:
          readOnly: true
        reviewed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        extraction_confidence:
          type: number
          format: double
          readOnly: true
          nullable: true
        classification_confidence:
          type: number
          format: double
          readOnly: true
          nullable: true
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/FinancialDocumentLineItem'
          readOnly: true
        summary:
          readOnly: true
          nullable: true
        source_document_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        document:
          allOf:
          - $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: Latest document with presigned URL
        journal_entry_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        posted_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - amount_due
      - amount_paid
      - business_id
      - classification_confidence
      - counterparty
      - created_at
      - currency
      - document
      - document_type
      - due_date
      - external_id
      - extraction_confidence
      - id
      - is_fully_paid
      - is_overdue
      - journal_entry_id
      - line_items
      - needs_review
      - payment_terms
      - posted_at
      - reference_date
      - reference_number
      - review_reasons
      - reviewed_at
      - source_document_id
      - status
      - subtotal
      - summary
      - tax_amount
      - total_amount
      - type
      - updated_at
      - workflow_type
    FinancialDocumentLineItem:
      type: object
      description: |-
        Serializer for FinancialDocument line items in responses.

        Performance Note:
        - Uses financial_document_id FK field directly (no relationship access needed)
        - When used via prefetch_related, ensure account and tax_code are selected
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        financial_document_id:
          type: string
          format: uuid
          readOnly: true
        line_number:
          type: integer
          readOnly: true
          description: Order of this line item on the document
        description:
          type: string
          readOnly: true
          description: Description of the line item
        sku:
          type: string
          readOnly: true
          nullable: true
          description: SKU or product code
        quantity:
          type: number
          format: float
          readOnly: true
        unit_price:
          type: integer
          readOnly: true
          description: Unit price in cents
        amount:
          type: integer
          readOnly: true
          description: Line amount in cents
        tax_rate:
          type: number
          format: float
          readOnly: true
          description: Tax rate as percentage (e.g., 21.0 for 21%)
        tax_amount:
          type: integer
          readOnly: true
          description: Tax amount in cents
        account_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
        account_code:
          type: string
          readOnly: true
          nullable: true
        tracking_categories:
          readOnly: true
          description: Tracking categories/dimensions for this line item
        metadata:
          readOnly: true
          description: Additional metadata
      required:
      - account_code
      - account_id
      - amount
      - description
      - financial_document_id
      - id
      - line_number
      - metadata
      - quantity
      - sku
      - tax_amount
      - tax_rate
      - tracking_categories
      - unit_price
    FinancialDocumentReviewActionRequest:
      type: object
      description: Serializer for the mark-as-reviewed action.
      properties:
        clear_review_reasons:
          type: boolean
          default: true
          description: Whether to clear the review reasons list
        notes:
          type: string
          description: Optional notes about the review
    FinancialDocumentUpdateAPIRequest:
      type: object
      description: |-
        Serializer for updating FinancialDocument fields.

        Supports limited updates - primarily for review workflow and corrections.
        Financial data updates should be done through proper correction workflows.
      properties:
        reference_number:
          type: string
          nullable: true
          description: Document reference number
        reference_date:
          type: string
          format: date
          nullable: true
          description: Document issue date
        due_date:
          type: string
          format: date
          nullable: true
          description: Payment due date
        payment_terms:
          type: string
          nullable: true
          description: Payment terms (e.g., 'Net 30')
        notes:
          type: string
          nullable: true
          description: Internal notes
        metadata:
          description: Additional metadata
    FinancialPortalLoginRequest:
      type: object
      description: Serializer for financial portal login requests
      properties:
        email:
          type: string
          format: email
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 1
      required:
      - email
      - password
    FinancialPortalTaskCreateRequest:
      type: object
      description: |-
        Serializer for creating tasks from Financial Admin Portal.

        Creates a task with an initial question message.
        The authenticated financial admin's user is set as created_by.
      properties:
        title:
          type: string
          minLength: 1
          description: Task title
          maxLength: 255
        description:
          type: string
          description: Task description
        first_question:
          type: string
          minLength: 1
          description: Initial question from the financial administrator
        due_date:
          type: string
          format: date
          nullable: true
          description: Optional due date for the task
        accounting_period:
          type: string
          format: uuid
          nullable: true
          description: Optional accounting period ID
      required:
      - first_question
      - title
    FinancialPortalTaskMessageCreateRequest:
      type: object
      description: |-
        Serializer for creating task messages from Financial Admin Portal.

        Financial admins can only add questions to existing tasks.
      properties:
        message_type:
          enum:
          - question
          type: string
          x-spec-enum-id: 9b7d911114f84e0d
          description: |-
            Message type (financial admins can only add questions)

            * `question` - question
        message:
          type: string
          minLength: 1
          description: Message content
      required:
      - message
      - message_type
    FinancialPortalToken:
      type: object
      description: Serializer for financial portal token responses
      properties:
        access_token:
          type: string
        expires_in:
          type: integer
        token_type:
          type: string
        user:
          type: object
          additionalProperties: {}
          nullable: true
          readOnly: true
      required:
      - access_token
      - expires_in
      - token_type
      - user
    FinancialSummary:
      type: object
      description: |-
        Complete financial summary response with trends.

        Includes:
        - Business and period metadata
        - Summary totals for entire period
        - Period-by-period trends (monthly, quarterly, or yearly)
      properties:
        business_id:
          type: string
          format: uuid
          description: Business UUID
        start_date:
          type: string
          format: date
          description: Report period start
        end_date:
          type: string
          format: date
          description: Report period end
        currency:
          type: string
          description: Business base currency (e.g., EUR, GBP, USD)
        granularity:
          enum:
          - monthly
          - quarterly
          - yearly
          type: string
          x-spec-enum-id: 56f5599b29705c7b
          description: |-
            Period granularity: 'monthly', 'quarterly', or 'yearly'

            * `monthly` - monthly
            * `quarterly` - quarterly
            * `yearly` - yearly
        summary:
          allOf:
          - $ref: '#/components/schemas/FinancialSummarySummary'
          description: Overall totals for entire date range
        trends:
          type: array
          items:
            $ref: '#/components/schemas/PeriodTrend'
          description: Period-by-period breakdown
      required:
      - business_id
      - currency
      - end_date
      - granularity
      - start_date
      - summary
      - trends
    FinancialSummarySummary:
      type: object
      description: |-
        Overall financial summary totals for the entire date range.

        - total_revenue_cents: Sum of all revenue
        - total_expenses_cents: Sum of all expenses (direct_costs + operating_expenses + finance_costs + income_tax)
        - net_profit_cents: Revenue - Expenses
      properties:
        total_revenue_cents:
          type: integer
          description: Total revenue for entire period in cents
        total_expenses_cents:
          type: integer
          description: Total expenses for entire period in cents
        net_profit_cents:
          type: integer
          description: Net profit for entire period in cents
      required:
      - net_profit_cents
      - total_expenses_cents
      - total_revenue_cents
    FixedAsset:
      type: object
      description: |-
        Fixed Asset serializer with auto-population.

        Auto-populates:
        - useful_life_months from country config (if not provided)
        - depreciation_start_date (calculated on save)
        - asset_number (generated on save)
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        business:
          type: string
          format: uuid
        asset_number:
          type: string
          readOnly: true
          description: 'Unique identifier (auto-generated: FA-YYYY-NNNN)'
        description:
          type: string
          description: Asset description (e.g., 'MacBook Pro 16-inch 2024')
          maxLength: 255
        category:
          enum:
          - computer_equipment
          - office_furniture
          - vehicles
          - machinery
          - buildings
          - leasehold_improvements
          - software
          - other
          type: string
          x-spec-enum-id: 853bec44a2bd14ca
          description: |-
            Asset category for grouping and reporting

            * `computer_equipment` - Computer Equipment
            * `office_furniture` - Office Furniture & Equipment
            * `vehicles` - Vehicles
            * `machinery` - Machinery & Equipment
            * `buildings` - Buildings
            * `leasehold_improvements` - Leasehold Improvements
            * `software` - Software & Licenses
            * `other` - Other Fixed Assets
        acquisition_date:
          type: string
          format: date
          description: Date asset was acquired/put into service
        supplier:
          type: string
          description: Supplier/vendor name (optional)
          maxLength: 255
        depreciation_method:
          enum:
          - straight_line
          - declining_balance
          type: string
          x-spec-enum-id: 0208219e8247f3d3
          description: |-
            Depreciation method

            * `straight_line` - Straight-Line
            * `declining_balance` - Declining Balance
        useful_life_months:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          description: Expected useful life in months
        depreciation_start_date:
          type: string
          format: date
          readOnly: true
          nullable: true
          description: Date to start depreciation (auto-calculated if not set)
        asset_account:
          type: string
          format: uuid
          description: GL account for asset cost (e.g., 1700)
        accumulated_depreciation_account:
          type: string
          format: uuid
          description: Contra-asset account for accumulated depreciation (e.g., 1710)
        depreciation_expense_account:
          type: string
          format: uuid
          description: P&L account for depreciation expense
        status:
          enum:
          - active
          - fully_depreciated
          - disposed
          type: string
          x-spec-enum-id: b474eebf8d73ba75
          readOnly: true
          description: |-
            Current asset status

            * `active` - Active
            * `fully_depreciated` - Fully Depreciated
            * `disposed` - Disposed
        location:
          type: string
          description: Physical location or department
          maxLength: 255
        serial_number:
          type: string
          description: Manufacturer serial number
          maxLength: 100
        metadata:
          description: Extensible field for custom attributes
        external_id:
          type: string
          description: External system identifier
          maxLength: 100
        net_book_value:
          type: integer
          description: Net book value in cents
          readOnly: true
        accumulated_depreciation:
          type: integer
          description: Accumulated depreciation in cents
          readOnly: true
        monthly_depreciation:
          type: integer
          description: Monthly depreciation amount in cents
          readOnly: true
        is_fully_depreciated:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        created_by:
          type: string
          description: User who created the asset
          maxLength: 100
      required:
      - accumulated_depreciation
      - accumulated_depreciation_account
      - acquisition_date
      - asset_account
      - asset_number
      - business
      - category
      - created_at
      - depreciation_expense_account
      - depreciation_start_date
      - description
      - id
      - is_fully_depreciated
      - monthly_depreciation
      - net_book_value
      - status
      - updated_at
      - useful_life_months
    FixedAssetDetail:
      type: object
      description: |-
        Detailed asset serializer with nested depreciation entries.
        Used for retrieve endpoint.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        business:
          type: string
          format: uuid
        asset_number:
          type: string
          readOnly: true
          description: 'Unique identifier (auto-generated: FA-YYYY-NNNN)'
        description:
          type: string
          description: Asset description (e.g., 'MacBook Pro 16-inch 2024')
          maxLength: 255
        category:
          enum:
          - computer_equipment
          - office_furniture
          - vehicles
          - machinery
          - buildings
          - leasehold_improvements
          - software
          - other
          type: string
          x-spec-enum-id: 853bec44a2bd14ca
          description: |-
            Asset category for grouping and reporting

            * `computer_equipment` - Computer Equipment
            * `office_furniture` - Office Furniture & Equipment
            * `vehicles` - Vehicles
            * `machinery` - Machinery & Equipment
            * `buildings` - Buildings
            * `leasehold_improvements` - Leasehold Improvements
            * `software` - Software & Licenses
            * `other` - Other Fixed Assets
        acquisition_date:
          type: string
          format: date
          description: Date asset was acquired/put into service
        supplier:
          type: string
          description: Supplier/vendor name (optional)
          maxLength: 255
        depreciation_method:
          enum:
          - straight_line
          - declining_balance
          type: string
          x-spec-enum-id: 0208219e8247f3d3
          description: |-
            Depreciation method

            * `straight_line` - Straight-Line
            * `declining_balance` - Declining Balance
        useful_life_months:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          description: Expected useful life in months
        depreciation_start_date:
          type: string
          format: date
          readOnly: true
          nullable: true
          description: Date to start depreciation (auto-calculated if not set)
        asset_account:
          type: string
          format: uuid
          description: GL account for asset cost (e.g., 1700)
        accumulated_depreciation_account:
          type: string
          format: uuid
          description: Contra-asset account for accumulated depreciation (e.g., 1710)
        depreciation_expense_account:
          type: string
          format: uuid
          description: P&L account for depreciation expense
        status:
          enum:
          - active
          - fully_depreciated
          - disposed
          type: string
          x-spec-enum-id: b474eebf8d73ba75
          readOnly: true
          description: |-
            Current asset status

            * `active` - Active
            * `fully_depreciated` - Fully Depreciated
            * `disposed` - Disposed
        location:
          type: string
          description: Physical location or department
          maxLength: 255
        serial_number:
          type: string
          description: Manufacturer serial number
          maxLength: 100
        metadata:
          description: Extensible field for custom attributes
        external_id:
          type: string
          description: External system identifier
          maxLength: 100
        net_book_value:
          type: integer
          description: Net book value in cents
          readOnly: true
        accumulated_depreciation:
          type: integer
          description: Accumulated depreciation in cents
          readOnly: true
        monthly_depreciation:
          type: integer
          description: Monthly depreciation amount in cents
          readOnly: true
        is_fully_depreciated:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        created_by:
          type: string
          description: User who created the asset
          maxLength: 100
        depreciation_entries:
          type: array
          items:
            $ref: '#/components/schemas/DepreciationEntry'
          readOnly: true
      required:
      - accumulated_depreciation
      - accumulated_depreciation_account
      - acquisition_date
      - asset_account
      - asset_number
      - business
      - category
      - created_at
      - depreciation_entries
      - depreciation_expense_account
      - depreciation_start_date
      - description
      - id
      - is_fully_depreciated
      - monthly_depreciation
      - net_book_value
      - status
      - updated_at
      - useful_life_months
    FixedAssetRequest:
      type: object
      description: |-
        Fixed Asset serializer with auto-population.

        Auto-populates:
        - useful_life_months from country config (if not provided)
        - depreciation_start_date (calculated on save)
        - asset_number (generated on save)
      properties:
        business:
          type: string
          format: uuid
        description:
          type: string
          minLength: 1
          description: Asset description (e.g., 'MacBook Pro 16-inch 2024')
          maxLength: 255
        category:
          enum:
          - computer_equipment
          - office_furniture
          - vehicles
          - machinery
          - buildings
          - leasehold_improvements
          - software
          - other
          type: string
          x-spec-enum-id: 853bec44a2bd14ca
          description: |-
            Asset category for grouping and reporting

            * `computer_equipment` - Computer Equipment
            * `office_furniture` - Office Furniture & Equipment
            * `vehicles` - Vehicles
            * `machinery` - Machinery & Equipment
            * `buildings` - Buildings
            * `leasehold_improvements` - Leasehold Improvements
            * `software` - Software & Licenses
            * `other` - Other Fixed Assets
        acquisition_date:
          type: string
          format: date
          description: Date asset was acquired/put into service
        supplier:
          type: string
          description: Supplier/vendor name (optional)
          maxLength: 255
        acquisition_cost_cents:
          type: integer
          minimum: 0
          writeOnly: true
          description: Acquisition cost in cents
        residual_value_cents:
          type: integer
          minimum: 0
          writeOnly: true
          description: Residual value in cents
        depreciation_method:
          enum:
          - straight_line
          - declining_balance
          type: string
          x-spec-enum-id: 0208219e8247f3d3
          description: |-
            Depreciation method

            * `straight_line` - Straight-Line
            * `declining_balance` - Declining Balance
        useful_life_months:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          description: Expected useful life in months
        asset_account:
          type: string
          format: uuid
          description: GL account for asset cost (e.g., 1700)
        accumulated_depreciation_account:
          type: string
          format: uuid
          description: Contra-asset account for accumulated depreciation (e.g., 1710)
        depreciation_expense_account:
          type: string
          format: uuid
          description: P&L account for depreciation expense
        location:
          type: string
          description: Physical location or department
          maxLength: 255
        serial_number:
          type: string
          description: Manufacturer serial number
          maxLength: 100
        metadata:
          description: Extensible field for custom attributes
        external_id:
          type: string
          description: External system identifier
          maxLength: 100
        created_by:
          type: string
          description: User who created the asset
          maxLength: 100
      required:
      - accumulated_depreciation_account
      - acquisition_date
      - asset_account
      - business
      - category
      - depreciation_expense_account
      - description
      - useful_life_months
    InternalAdminLoginRequest:
      type: object
      description: Serializer for internal admin login requests
      properties:
        email:
          type: string
          format: email
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 1
      required:
      - email
      - password
    InternalAdminToken:
      type: object
      description: Serializer for internal admin token responses
      properties:
        access_token:
          type: string
        expires_in:
          type: integer
        token_type:
          type: string
        user:
          type: object
          additionalProperties: {}
          nullable: true
          readOnly: true
      required:
      - access_token
      - expires_in
      - token_type
      - user
    InternalBusiness:
      type: object
      description: Serializer for business list (internal admin view)
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        legal_name:
          type: string
          readOnly: true
        external_id:
          type: string
          readOnly: true
        partner:
          type: string
          format: uuid
          readOnly: true
        partner_name:
          type: string
          readOnly: true
        email:
          type: string
          format: email
          readOnly: true
        country:
          enum:
          - GB
          - DE
          - FR
          - NL
          - ES
          - IT
          - IE
          - BE
          - AT
          - PT
          - SE
          - 'NO'
          - DK
          - FI
          - IS
          - MY
          - SG
          type: string
          description: |-
            * `GB` - United Kingdom
            * `DE` - Germany
            * `FR` - France
            * `NL` - Netherlands
            * `ES` - Spain
            * `IT` - Italy
            * `IE` - Ireland
            * `BE` - Belgium
            * `AT` - Austria
            * `PT` - Portugal
            * `SE` - Sweden
            * `NO` - Norway
            * `DK` - Denmark
            * `FI` - Finland
            * `IS` - Iceland
            * `MY` - Malaysia
            * `SG` - Singapore
          x-spec-enum-id: f4d5c691ea686889
          readOnly: true
        base_currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - base_currency
      - country
      - created_at
      - email
      - external_id
      - id
      - is_active
      - legal_name
      - name
      - partner
      - partner_name
      - updated_at
    InternalPartner:
      type: object
      description: Serializer for partner list (internal admin view)
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        subdomain:
          type: string
          readOnly: true
        industry:
          type: string
          readOnly: true
        subscription_tier:
          type: string
          readOnly: true
        monthly_transaction_limit:
          type: integer
          readOnly: true
        portal_enabled:
          type: boolean
          readOnly: true
          description: Enable partner portal access
        max_portal_users:
          type: integer
          readOnly: true
          description: Maximum number of partner portal users
        is_active:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        total_businesses:
          type: integer
          readOnly: true
      required:
      - created_at
      - id
      - industry
      - is_active
      - max_portal_users
      - monthly_transaction_limit
      - name
      - portal_enabled
      - subdomain
      - subscription_tier
      - total_businesses
      - updated_at
    InternalUser:
      type: object
      description: Serializer for user list (internal admin view)
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        email:
          type: string
          format: email
          readOnly: true
          title: Email address
        username:
          type: string
          readOnly: true
          description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
            only.
        first_name:
          type: string
          readOnly: true
        last_name:
          type: string
          readOnly: true
        user_type:
          enum:
          - direct_user
          - partner_admin
          - financial_administrator
          - internal_admin
          - business_owner
          type: string
          description: |-
            * `direct_user` - Direct User
            * `partner_admin` - Partner Administrator
            * `financial_administrator` - Financial Administrator
            * `internal_admin` - Internal Administrator
            * `business_owner` - Business Owner
          x-spec-enum-id: f12d905e2a1759ac
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
          title: Active
          description: Designates whether this user should be treated as active. Unselect
            this instead of deleting accounts.
        is_staff:
          type: boolean
          readOnly: true
          title: Staff status
          description: Designates whether the user can log into this admin site.
        is_superuser:
          type: boolean
          readOnly: true
          title: Superuser status
          description: Designates that this user has all permissions without explicitly
            assigning them.
        partner_name:
          type: string
          readOnly: true
          nullable: true
        financial_firm_name:
          type: string
          readOnly: true
          nullable: true
        date_joined:
          type: string
          format: date-time
          readOnly: true
        last_login:
          type: string
          format: date-time
          readOnly: true
          nullable: true
      required:
      - date_joined
      - email
      - financial_firm_name
      - first_name
      - id
      - is_active
      - is_staff
      - is_superuser
      - last_login
      - last_name
      - partner_name
      - user_type
      - username
    Invoice:
      type: object
      description: |-
        Invoice serializer for API responses
        All monetary amounts are returned in cents
      properties:
        type:
          type: string
          description: Resource type identifier
          readOnly: true
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique invoice identifier
        business_id:
          type: string
          format: uuid
          readOnly: true
          description: Business this invoice belongs to
        external_id:
          type: string
          description: External system identifier
        status:
          type: string
          enum:
          - DRAFT
          - SENT
          - PAID
          - PARTIALLY_PAID
          - OVERDUE
          - CANCELLED
          - REFUNDED
          example: SENT
          readOnly: true
          description: Invoice status in uppercase format
        sent_at:
          type: string
          format: date-time
          readOnly: true
          description: When the invoice was sent to customer
        due_at:
          type: string
          format: date-time
          description: When payment is due (ISO timestamp)
          readOnly: true
        paid_at:
          type: string
          format: date-time
          readOnly: true
          description: When the invoice was fully paid
        voided_at:
          type: string
          format: date-time
          nullable: true
          readOnly: true
          description: When the invoice was voided (always null - we use cancelled
            status)
        is_overdue:
          type: boolean
          description: True if invoice is past due date and has outstanding balance
          example: false
          readOnly: true
        invoice_number:
          type: string
          description: Invoice number for display and reference
          maxLength: 100
        invoice_type:
          enum:
          - invoice
          - receipt
          type: string
          x-spec-enum-id: 026df2e18581a7be
          readOnly: true
          description: |-
            Type of invoice: invoice or receipt

            * `invoice` - Invoice
            * `receipt` - Receipt
        currency:
          type: string
          readOnly: true
          description: ISO 4217 currency code (e.g., EUR, GBP, USD)
          maxLength: 3
        memo:
          type: string
          description: Invoice description or memo
        customer:
          allOf:
          - $ref: '#/components/schemas/Customer'
          readOnly: true
          description: Customer information
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLineItem'
          readOnly: true
          description: Array of invoice line items
        subtotal:
          type: integer
          description: Subtotal amount in cents before taxes
          readOnly: true
        additional_discount:
          type: integer
          description: Additional invoice-level discount in cents
          readOnly: true
        additional_sales_taxes:
          type: array
          items:
            $ref: '#/components/schemas/AdditionalSalesTax'
          readOnly: true
          description: Additional sales taxes array
        additional_sales_taxes_total:
          type: integer
          description: Total additional sales taxes in cents
          readOnly: true
        tips:
          type: integer
          description: Tips amount in cents
          readOnly: true
        tips_account:
          type: string
          nullable: true
          readOnly: true
          description: Tips account information
        total_amount:
          type: integer
          description: Total invoice amount in cents including taxes
          readOnly: true
        outstanding_balance:
          type: integer
          description: Outstanding balance in cents
          readOnly: true
        payment_allocations:
          type: array
          items:
            $ref: '#/components/schemas/InvoicePaymentAllocationSummary'
          readOnly: true
          description: Array of payment allocations
        credit_allocations:
          type: array
          items:
            $ref: '#/components/schemas/CustomerCreditAllocationSummary'
          readOnly: true
          description: Array of customer credit note allocations
        refund_allocations:
          type: array
          items:
            $ref: '#/components/schemas/RefundAllocationSummary'
          readOnly: true
          description: Array of refund allocations
        write_offs:
          type: array
          items:
            $ref: '#/components/schemas/WriteOffSummary'
          readOnly: true
          description: Array of write-offs on this invoice
        document:
          allOf:
          - $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: Latest invoice document file with presigned URL
        imported_at:
          type: string
          format: date-time
          readOnly: true
          description: When the invoice was imported/created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: When the invoice was last updated
      required:
      - additional_discount
      - additional_sales_taxes
      - additional_sales_taxes_total
      - business_id
      - credit_allocations
      - currency
      - customer
      - document
      - due_at
      - id
      - imported_at
      - invoice_number
      - invoice_type
      - is_overdue
      - line_items
      - outstanding_balance
      - paid_at
      - payment_allocations
      - refund_allocations
      - sent_at
      - status
      - subtotal
      - tips
      - tips_account
      - total_amount
      - type
      - updated_at
      - voided_at
      - write_offs
    InvoiceCreateAPIRequest:
      type: object
      description: |-
        Invoice creation serializer for API requests
        Maps API format to internal models and creates invoices with line items
      properties:
        external_id:
          type: string
          minLength: 1
          description: External system identifier for this invoice
        sent_at:
          type: string
          format: date-time
          description: When the invoice was sent (ISO 8601 format)
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLineItemCreateRequest'
          description: Array of line items for this invoice
        due_at:
          type: string
          format: date-time
          description: When payment is due (ISO 8601 format). Defaults to 30 days
            from sent_at
        voided_at:
          type: string
          format: date-time
          description: When the invoice was voided (not used - we use cancelled status)
        invoice_number:
          type: string
          description: Invoice number for display. Auto-generated if not provided
        invoice_type:
          enum:
          - invoice
          - receipt
          type: string
          x-spec-enum-id: 026df2e18581a7be
          default: invoice
          description: |-
            Type of invoice: invoice or receipt

            * `invoice` - Invoice
            * `receipt` - Receipt
        customer_id:
          type: string
          format: uuid
          nullable: true
          description: Existing customer ID to assign invoice to
        customer_external_id:
          type: string
          description: External customer ID. Will create customer if not found
        memo:
          type: string
          description: Invoice description or memo
        additional_discount:
          type: integer
          default: 0
          description: Additional invoice-level discount in cents
        additional_sales_taxes:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Array of additional tax objects
        additional_sales_taxes_total:
          type: integer
          default: 0
          description: Total additional sales taxes in cents
        tips:
          type: integer
          default: 0
          description: Tips amount in cents
        tips_account:
          nullable: true
          description: Tips account information
        transaction_tags:
          type: array
          items:
            type: string
            minLength: 1
          description: Array of transaction tags for categorization
        metadata:
          description: Additional metadata for the invoice
        document:
          allOf:
          - $ref: '#/components/schemas/InvoiceDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
      required:
      - external_id
      - line_items
      - sent_at
    InvoiceDocumentUploadRequest:
      type: object
      description: Invoice specific document upload payload
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: sales_invoice
        upload_source:
          type: string
        metadata: {}
        tags: {}
    InvoiceLineItem:
      type: object
      description: |-
        Serializer for invoice line items
        All monetary amounts are returned in cents
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique identifier for the line item
        external_id:
          type: string
          description: External system identifier for this line item
        invoice_id:
          type: string
          format: uuid
          readOnly: true
          description: Invoice this line item belongs to
        account_identifier:
          allOf:
          - $ref: '#/components/schemas/AccountIdentifier'
          nullable: true
          readOnly: true
          description: Account identifier for revenue posting
        description:
          type: string
          description: Description of the product or service
          maxLength: 500
        product:
          type: string
          description: Product code or SKU
        unit_price:
          type: integer
          description: Unit price in cents
          readOnly: true
        quantity:
          type: number
          format: float
          description: Quantity of items
          readOnly: true
        subtotal:
          type: integer
          description: Subtotal before taxes in cents
          readOnly: true
        discount_amount:
          type: integer
          description: Discount amount in cents
          readOnly: true
        sales_taxes_total:
          type: integer
          description: Total tax amount in cents
          readOnly: true
        total_amount:
          type: integer
          description: Total amount including taxes in cents
          readOnly: true
      required:
      - account_identifier
      - description
      - discount_amount
      - id
      - invoice_id
      - quantity
      - sales_taxes_total
      - subtotal
      - total_amount
      - unit_price
    InvoiceLineItemCreateRequest:
      type: object
      description: Serializer for invoice line items in creation format
      properties:
        external_id:
          type: string
          description: External system identifier for this line item
        description:
          type: string
          description: Description of the product or service
        account_identifier:
          nullable: true
          description: Revenue account identifier for posting
        product:
          type: string
          description: Product code or SKU
        quantity:
          type: number
          format: double
          description: Quantity of items/hours
        unit_price:
          type: integer
          description: Unit price in cents
        discount_amount:
          type: integer
          default: 0
          description: Discount amount in cents
        sales_taxes:
          type: array
          items:
            $ref: '#/components/schemas/TaxLineItemRequest'
          description: Array of tax line items
      required:
      - quantity
      - unit_price
    InvoiceLineItemRequest:
      type: object
      description: |-
        Serializer for invoice line items
        All monetary amounts are returned in cents
      properties:
        external_id:
          type: string
          description: External system identifier for this line item
        description:
          type: string
          minLength: 1
          description: Description of the product or service
          maxLength: 500
        product:
          type: string
          description: Product code or SKU
      required:
      - description
    InvoicePaymentAllocationDetail:
      type: object
      description: |-
        Enhanced allocation serializer with invoice status information
        for the invoice payments list endpoint
        All amounts in cents
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        invoice_id:
          type: string
          format: uuid
          readOnly: true
          description: UUID of the invoice
        invoice_number:
          type: string
          readOnly: true
          description: Invoice number (e.g., INV-0042)
        invoice_status:
          type: string
          readOnly: true
          description: Current invoice status (sent, paid, overdue, etc.)
        amount:
          type: integer
          description: Amount allocated to this invoice in cents
          readOnly: true
        allocated_at:
          type: string
          format: date-time
          readOnly: true
          description: Date and time when allocation was created
        transaction_tags: {}
        notes:
          type: string
      required:
      - allocated_at
      - amount
      - id
      - invoice_id
      - invoice_number
      - invoice_status
    InvoicePaymentAllocationSummary:
      type: object
      description: Payment allocation summary for invoice detail view.
      properties:
        amount_cents:
          type: integer
        payment_date:
          type: string
          format: date
        payment_method:
          type: string
        payment_id:
          type: string
          format: uuid
      required:
      - amount_cents
      - payment_date
      - payment_id
      - payment_method
    InvoicePaymentDeleteResponse:
      type: object
      description: Response serializer for invoice payment deletion
      properties:
        message:
          type: string
          description: Status message
        payment_id:
          type: string
          format: uuid
          description: UUID of the deleted payment
        status:
          type: string
          description: New status of the payment
        updated_at:
          type: string
          format: date-time
          description: When the payment was updated
      required:
      - message
      - payment_id
      - status
      - updated_at
    InvoicePaymentList:
      type: object
      description: |-
        Comprehensive serializer for invoice payments list endpoint.
        Extends PaymentSerializer with allocation details.

        Inspired by external payment APIs but adapted for Friday's architecture.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        external_id:
          type: string
          maxLength: 255
        payment_reference:
          type: string
          maxLength: 100
        processor_reference:
          type: string
          maxLength: 255
        customer:
          allOf:
          - $ref: '#/components/schemas/CustomerEmbedded'
          nullable: true
          readOnly: true
        customer_name:
          type: string
          readOnly: true
          description: Customer display name
        customer_email:
          type: string
          readOnly: true
          description: Customer email address
        payment_date:
          type: string
          format: date-time
        payment_method:
          enum:
          - bank_transfer
          - credit_card
          - debit_card
          - ach
          - check
          - cash
          - paypal
          - stripe
          - other
          type: string
          description: |-
            * `bank_transfer` - Bank Transfer
            * `credit_card` - Credit Card
            * `debit_card` - Debit Card
            * `ach` - ACH/Direct Debit
            * `check` - Check/Cheque
            * `cash` - Cash
            * `paypal` - PayPal
            * `stripe` - Stripe
            * `other` - Other
          x-spec-enum-id: 77fedb01429a0eb2
        payment_processor:
          type: string
          maxLength: 100
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
        total_amount:
          type: integer
          description: Total payment amount in cents
          readOnly: true
        allocated_amount:
          type: integer
          description: Amount allocated to invoices in cents
          readOnly: true
        unallocated_amount:
          type: integer
          description: Unallocated amount remaining in cents (customer credit if positive)
          readOnly: true
        net_amount:
          type: integer
          description: Net amount after deducting all fees in cents
          readOnly: true
        processing_fee:
          type: integer
          description: Platform processing fee charged in cents
          readOnly: true
        processing_fee_cents:
          type: integer
          readOnly: true
          description: Platform processing fee charged in cents (raw database field)
        display_amount:
          type: string
          readOnly: true
          description: Human-readable payment amount with currency symbol
        status:
          enum:
          - pending
          - processing
          - completed
          - failed
          - cancelled
          - refunded
          type: string
          description: |-
            * `pending` - Pending
            * `processing` - Processing
            * `completed` - Completed
            * `failed` - Failed
            * `cancelled` - Cancelled
            * `refunded` - Refunded
          x-spec-enum-id: 760241f0a4b58134
        is_fully_allocated:
          type: boolean
          readOnly: true
          description: Whether payment is fully allocated to invoices (true if allocated_amount
            >= total_amount)
        is_completed:
          type: boolean
          readOnly: true
          description: Whether payment processing is completed (status='completed')
        processed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        failed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        failure_reason:
          type: string
        transaction_tags: {}
        metadata: {}
        notes:
          type: string
        bank_reference:
          type: string
          maxLength: 100
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/InvoicePaymentAllocationDetail'
          readOnly: true
        refund_allocations:
          type: array
          items:
            $ref: '#/components/schemas/PaymentRefundAllocationSummary'
          readOnly: true
          description: Refund allocations linked to this payment
        reconciled_bank_transactions:
          type: array
          items:
            $ref: '#/components/schemas/EntityReconciliationDetail'
          readOnly: true
          description: Bank transactions this payment is reconciled to
      required:
      - allocated_amount
      - allocations
      - created_at
      - customer
      - customer_email
      - customer_name
      - display_amount
      - failed_at
      - id
      - is_completed
      - is_fully_allocated
      - net_amount
      - payment_method
      - processed_at
      - processing_fee
      - processing_fee_cents
      - reconciled_bank_transactions
      - refund_allocations
      - total_amount
      - unallocated_amount
      - updated_at
    InvoiceReconciliationRequestRequest:
      type: object
      description: Request serializer for invoice payment reconciliation
      properties:
        notes:
          type: string
          description: Optional notes for the reconciliation
          maxLength: 500
        evidence:
          type: object
          additionalProperties: {}
          description: Supporting evidence for the reconciliation
        created_by:
          enum:
          - api
          - manual
          - auto
          - import
          type: string
          x-spec-enum-id: 5993daf453316fc6
          default: api
          description: |-
            Source of reconciliation (api, manual, auto, import)

            * `api` - api
            * `manual` - manual
            * `auto` - auto
            * `import` - import
        invoice_id:
          type: string
          format: uuid
          description: Invoice ID to reconcile
        payment_method:
          enum:
          - bank_transfer
          - credit_card
          - debit_card
          - ach
          - check
          - cash
          - wire
          - paypal
          - stripe
          - other
          type: string
          x-spec-enum-id: 6a4918e6dc1589b2
          default: bank_transfer
          description: |-
            Payment method for the reconciliation

            * `bank_transfer` - bank_transfer
            * `credit_card` - credit_card
            * `debit_card` - debit_card
            * `ach` - ach
            * `check` - check
            * `cash` - cash
            * `wire` - wire
            * `paypal` - paypal
            * `stripe` - stripe
            * `other` - other
        amount_cents:
          type: integer
          minimum: 1
          nullable: true
          description: Amount to reconcile in cents. If not provided, uses min(outstanding,
            bank_remaining).
      required:
      - invoice_id
    InvoiceRecordPaymentRequestRequest:
      type: object
      description: Request serializer for recording invoice payments
      properties:
        customer_id:
          type: string
          format: uuid
          description: UUID of the customer making the payment (must exist in business)
        total_amount_cents:
          type: integer
          minimum: 1
          description: Total payment amount in cents (e.g., 450000 for £4,500.00)
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/PaymentAllocationItemRequest'
          description: List of invoice allocations - how this payment should be applied
            to invoices
        payment_date:
          type: string
          format: date
          description: 'Date when payment was received (ISO date format: YYYY-MM-DD)'
        currency:
          type: string
          minLength: 1
          description: Payment currency (must match business base currency, e.g.,
            GBP, EUR)
          maxLength: 3
        payment_method:
          enum:
          - bank_transfer
          - credit_card
          - debit_card
          - ach
          - check
          - cash
          - paypal
          - stripe
          - other
          type: string
          x-spec-enum-id: 1a9252035ec0bc4a
          description: |-
            Method of payment (e.g., bank_transfer, card, cash, cheque, direct_debit)

            * `bank_transfer` - bank_transfer
            * `credit_card` - credit_card
            * `debit_card` - debit_card
            * `ach` - ach
            * `check` - check
            * `cash` - cash
            * `paypal` - paypal
            * `stripe` - stripe
            * `other` - other
        payment_reference:
          type: string
          description: Your internal payment reference or receipt number
        external_id:
          type: string
          description: Your unique identifier for this payment (used for idempotency)
        note:
          type: string
          description: Internal note or description for the payment
        notes:
          type: string
          description: Legacy field for notes (use 'note' instead)
        metadata:
          type: object
          additionalProperties: {}
          description: Custom key-value pairs for additional payment context
        references:
          type: object
          additionalProperties:
            type: string
          description: Payment references (bank_reference, end_to_end_id, payment_reference)
        processing_fee_cents:
          type: integer
          minimum: 0
          default: 0
          description: Processing fee charged by payment processor (Stripe, PayPal,
            etc.) in cents
        payment_processor:
          type: string
          description: Payment processor name (e.g., Stripe, PayPal)
          maxLength: 100
      required:
      - customer_id
      - total_amount_cents
    InvoiceRequest:
      type: object
      description: |-
        Invoice serializer for API responses
        All monetary amounts are returned in cents
      properties:
        external_id:
          type: string
          description: External system identifier
        invoice_number:
          type: string
          minLength: 1
          description: Invoice number for display and reference
          maxLength: 100
        memo:
          type: string
          description: Invoice description or memo
        customer_id:
          type: string
          format: uuid
          writeOnly: true
          description: Customer ID for invoice creation
      required:
      - invoice_number
    InvoiceStats:
      type: object
      description: Statistics for customer invoices.
      properties:
        all:
          type: integer
          description: Total number of invoices
        unpaid:
          type: integer
          description: Number of unpaid invoices (draft, issued, sent, partially_paid,
            partially_written_off)
        paid:
          type: integer
          description: Number of fully paid invoices
      required:
      - all
      - paid
      - unpaid
    InvoiceUnreconciliationRequestRequest:
      type: object
      description: Request serializer for invoice payment unreconciliation
      properties:
        invoice_id:
          type: string
          format: uuid
          description: Invoice ID to unreconcile
      required:
      - invoice_id
    InvoiceUpdateRequest:
      type: object
      description: |-
        Invoice update serializer that preserves payments, refunds, and writeoffs
        Only allows updates to safe fields that don't break accounting integrity
      properties:
        invoice_number:
          type: string
          minLength: 1
          description: Invoice number for display and reference
          maxLength: 100
        invoice_type:
          enum:
          - invoice
          - receipt
          type: string
          x-spec-enum-id: 026df2e18581a7be
          description: |-
            Type of invoice: invoice or receipt

            * `invoice` - Invoice
            * `receipt` - Receipt
        memo:
          type: string
          description: Invoice description or memo
        external_id:
          type: string
          description: External system identifier
        due_at:
          type: string
          format: date-time
          description: When payment is due (ISO 8601 format)
        document:
          allOf:
          - $ref: '#/components/schemas/InvoiceDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
        customer_id:
          type: string
          format: uuid
          description: Customer ID to assign invoice to
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLineItemCreateRequest'
          description: Array of line items for this invoice
        additional_discount:
          type: integer
          description: Additional invoice-level discount in cents
        additional_sales_taxes_total:
          type: integer
          description: Total additional sales taxes in cents
        tips:
          type: integer
          description: Tips amount in cents
    InvoiceUploadRequestRequest:
      type: object
      description: Request serializer for invoice upload endpoint
      properties:
        file:
          type: string
          format: binary
          description: PDF file to upload (max 50MB)
      required:
      - file
    InvoiceUploadResponse:
      type: object
      description: Response serializer for invoice upload endpoint
      properties:
        document_id:
          type: string
          format: uuid
          description: Unique identifier for the uploaded document
        task_id:
          type: string
          description: Celery task ID for tracking processing
        status:
          type: string
          description: Current status (always 'processing' initially)
        message:
          type: string
          description: Instructions for checking extraction result
      required:
      - document_id
      - message
      - status
      - task_id
    JournalEntryDetail:
      type: object
      description: Detailed serializer for journal entry with all lines.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique journal entry identifier
        sequence_number:
          type: string
          readOnly: true
          description: Sequential journal entry number (e.g., 'JE-2024-0042')
        entry_date:
          type: string
          format: date
          readOnly: true
          description: Date of the journal entry (YYYY-MM-DD)
        reference:
          type: string
          readOnly: true
          description: Journal entry reference number or source document reference
        description:
          type: string
          readOnly: true
          description: Journal entry description
        currency:
          type: string
          description: Entry currency from business base currency (GBP, EUR, USD)
          readOnly: true
        total_debit:
          type: integer
          description: Total debit amount in cents (sum of all debit lines)
          readOnly: true
        total_credit:
          type: integer
          description: Total credit amount in cents (sum of all credit lines)
          readOnly: true
        is_balanced:
          type: boolean
          readOnly: true
          description: Whether debits equal credits (balanced entry required for posting)
        created_by:
          enum:
          - ai
          - manual
          - system
          - import
          type: string
          x-spec-enum-id: 6007642db49bb795
          readOnly: true
          description: |-
            Creator type: ai, manual, system, import

            * `ai` - AI System
            * `manual` - Manual Entry
            * `system` - System Generated
            * `import` - Data Import
        created_by_display:
          type: string
          description: Human-readable creator type
          readOnly: true
        status:
          enum:
          - draft
          - approved
          - rejected
          type: string
          x-spec-enum-id: 497c72e056439a37
          readOnly: true
          description: |-
            Entry status: draft, approved, rejected

            * `draft` - Draft
            * `approved` - Approved
            * `rejected` - Rejected
        status_display:
          type: string
          description: Human-readable status
          readOnly: true
        is_posted:
          type: boolean
          readOnly: true
          description: Whether entry is posted to ledger (affects account balances)
        posted_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          description: Timestamp when entry was posted to ledger (null if not posted)
        bank_transaction_id:
          type: string
          nullable: true
          description: Linked bank transaction UUID (null if not from bank feed)
          readOnly: true
        source_type:
          type: string
          nullable: true
          description: Source document type (invoice, bill, payment, bank_transaction,
            etc.)
          readOnly: true
        source_reference:
          type: string
          nullable: true
          description: Source document reference number
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when entry was created
        accounting_period:
          type: object
          additionalProperties: {}
          nullable: true
          description: Accounting period this entry belongs to (year, month, period
            name, status)
          readOnly: true
        lines:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: All debit and credit lines for this journal entry
          readOnly: true
        source_info:
          allOf:
          - $ref: '#/components/schemas/SourceInfo'
          readOnly: true
          description: Source document information (invoice, bill, bank transaction,
            etc.) with links to original documents
        rejection_reason:
          type: string
          nullable: true
          description: Reason for rejection if status is rejected (null otherwise)
        rejected_at:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when entry was rejected (null if not rejected)
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
      required:
      - accounting_period
      - bank_transaction_id
      - created_at
      - created_by
      - created_by_display
      - currency
      - description
      - entry_date
      - id
      - is_balanced
      - is_posted
      - lines
      - posted_at
      - reference
      - sequence_number
      - source_info
      - source_reference
      - source_type
      - status
      - status_display
      - total_credit
      - total_debit
      - updated_at
    JournalEntryList:
      type: object
      description: Serializer for listing journal entries with totals.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique journal entry identifier
        sequence_number:
          type: string
          readOnly: true
          description: Sequential journal entry number (e.g., 'JE-2024-0042')
        entry_date:
          type: string
          format: date
          readOnly: true
          description: Date of the journal entry (YYYY-MM-DD)
        reference:
          type: string
          readOnly: true
          description: Journal entry reference number or source document reference
        description:
          type: string
          readOnly: true
          description: Journal entry description
        currency:
          type: string
          description: Entry currency from business base currency (GBP, EUR, USD)
          readOnly: true
        total_debit:
          type: integer
          description: Total debit amount in cents (sum of all debit lines)
          readOnly: true
        total_credit:
          type: integer
          description: Total credit amount in cents (sum of all credit lines)
          readOnly: true
        is_balanced:
          type: boolean
          readOnly: true
          description: Whether debits equal credits (balanced entry required for posting)
        created_by:
          enum:
          - ai
          - manual
          - system
          - import
          type: string
          x-spec-enum-id: 6007642db49bb795
          readOnly: true
          description: |-
            Creator type: ai, manual, system, import

            * `ai` - AI System
            * `manual` - Manual Entry
            * `system` - System Generated
            * `import` - Data Import
        created_by_display:
          type: string
          description: Human-readable creator type
          readOnly: true
        status:
          enum:
          - draft
          - approved
          - rejected
          type: string
          x-spec-enum-id: 497c72e056439a37
          readOnly: true
          description: |-
            Entry status: draft, approved, rejected

            * `draft` - Draft
            * `approved` - Approved
            * `rejected` - Rejected
        status_display:
          type: string
          description: Human-readable status
          readOnly: true
        is_posted:
          type: boolean
          readOnly: true
          description: Whether entry is posted to ledger (affects account balances)
        posted_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          description: Timestamp when entry was posted to ledger (null if not posted)
        bank_transaction_id:
          type: string
          nullable: true
          description: Linked bank transaction UUID (null if not from bank feed)
          readOnly: true
        source_type:
          type: string
          nullable: true
          description: Source document type (invoice, bill, payment, bank_transaction,
            etc.)
          readOnly: true
        source_reference:
          type: string
          nullable: true
          description: Source document reference number
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when entry was created
      required:
      - bank_transaction_id
      - created_at
      - created_by
      - created_by_display
      - currency
      - description
      - entry_date
      - id
      - is_balanced
      - is_posted
      - posted_at
      - reference
      - sequence_number
      - source_reference
      - source_type
      - status
      - status_display
      - total_credit
      - total_debit
    LineItem:
      type: object
      description: |-
        Individual account line item in P&L report.

        Represents a single Account with its period balance.
      properties:
        account_id:
          type: string
          format: uuid
          description: Account UUID (from Account.id)
        account_code:
          type: string
          description: Account code (from Account.code)
        account_name:
          type: string
          description: Account name (from Account.custom_name or Account.name)
        value_cents:
          type: integer
          description: Period balance in cents
      required:
      - account_code
      - account_id
      - account_name
      - value_cents
    LinkTokenRequest:
      type: object
      description: Serializer for link token creation request.
      properties:
        country_code:
          type: string
          minLength: 1
          default: US
          description: ISO country code (US, CA, GB, FR, ES, NL, IE). Defaults to
            'US'
          maxLength: 2
    LinkTokenResponse:
      type: object
      description: Serializer for link token creation response.
      properties:
        success:
          type: boolean
          description: Whether the operation was successful
        message:
          type: string
          description: Human-readable message
        link_token:
          type: string
          description: Plaid link token for frontend initialization
        expiration:
          type: string
          format: date-time
          description: Token expiration time (4 hours from creation)
      required:
      - message
      - success
    LinkedDocument:
      type: object
      description: |-
        Serializer for linked document information in journal entries.

        Represents a source document (invoice, bill, credit note, etc.) that
        generated this journal entry, with optional file attachment.
      properties:
        type:
          type: string
          description: Entity type (e.g., 'invoice', 'bill', 'vendorcreditnote')
        app_label:
          type: string
          description: Django app label containing the model
        id:
          type: string
          format: uuid
          description: Unique identifier of the linked entity
        created_at:
          type: string
          format: date-time
          nullable: true
          description: When the link was created
        reference:
          type: string
          description: Reference number (invoice number, bill number, etc.)
        display_name:
          type: string
          description: Human-readable display name for the entity
        file_link:
          allOf:
          - $ref: '#/components/schemas/FileLink'
          nullable: true
          description: Presigned URL and metadata for attached document. Only present
            if a document is attached.
      required:
      - app_label
      - id
      - type
    LoginRequest:
      type: object
      description: Serializer for user login.
      properties:
        email:
          type: string
          format: email
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 1
      required:
      - email
      - password
    MatchCustomerCreditNoteRequestRequest:
      type: object
      description: Request serializer for matching customer credit note to bank transaction
      properties:
        customer_credit_note_id:
          type: string
          format: uuid
          description: UUID of the customer credit note to match
        amount_cents:
          type: integer
          minimum: 1
          description: Amount to match in cents. If not provided, defaults to the
            reconcilable amount.
        notes:
          type: string
          description: Optional notes about this reconciliation match
      required:
      - customer_credit_note_id
    MatchCustomerCreditNoteResponse:
      type: object
      description: Response serializer for match customer credit note operation
      properties:
        reconciliation_link_id:
          type: string
          format: uuid
          description: ID of the created reconciliation link
        customer_credit_note:
          type: object
          additionalProperties: {}
          description: Updated customer credit note details
        bank_transaction:
          type: object
          additionalProperties: {}
          description: Updated bank transaction details
        matched_amount_cents:
          type: integer
          description: Amount matched in cents
      required:
      - bank_transaction
      - customer_credit_note
      - matched_amount_cents
      - reconciliation_link_id
    MatchPayoutRequestRequest:
      type: object
      description: Request serializer for matching payout to bank transaction
      properties:
        payout_id:
          type: string
          format: uuid
          description: UUID of the payout to match
        notes:
          type: string
          description: Optional notes about this reconciliation match
        created_by:
          type: string
          minLength: 1
          default: api
          description: 'Who created this match (default: ''api'')'
      required:
      - payout_id
    MatchPayoutResponse:
      type: object
      description: Response serializer for match payout operation
      properties:
        reconciliation_link:
          type: object
          additionalProperties: {}
          description: Created ReconciliationLink details
        payout:
          type: object
          additionalProperties: {}
          description: Updated payout with reconciliation_status
        bank_transaction:
          type: object
          additionalProperties: {}
          description: Updated bank transaction with unreconciled amounts
      required:
      - bank_transaction
      - payout
      - reconciliation_link
    MatchVendorCreditNoteRequestRequest:
      type: object
      description: Request serializer for matching vendor credit note to bank transaction
      properties:
        vendor_credit_note_id:
          type: string
          format: uuid
          description: UUID of the vendor credit note to match
        amount_cents:
          type: integer
          minimum: 1
          description: Amount to match in cents. If not provided, defaults to the
            reconcilable amount.
        notes:
          type: string
          description: Optional notes about this reconciliation match
      required:
      - vendor_credit_note_id
    MatchVendorCreditNoteResponse:
      type: object
      description: Response serializer for match vendor credit note operation
      properties:
        reconciliation_link_id:
          type: string
          format: uuid
          description: ID of the created reconciliation link
        vendor_credit_note:
          type: object
          additionalProperties: {}
          description: Updated vendor credit note details
        bank_transaction:
          type: object
          additionalProperties: {}
          description: Updated bank transaction details
        matched_amount_cents:
          type: integer
          description: Amount matched in cents
      required:
      - bank_transaction
      - matched_amount_cents
      - reconciliation_link_id
      - vendor_credit_note
    MenuConfig:
      type: object
      description: |-
        Serializer for menu configuration read operations.
        Returns the effective menu config for a business.
      properties:
        menu:
          type: object
          additionalProperties:
            type: boolean
          description: Menu items visibility configuration
        sub_menu_tabs:
          type: object
          additionalProperties:
            type: boolean
          description: Sub-menu tabs visibility configuration
        source:
          enum:
          - business
          - partner
          type: string
          x-spec-enum-id: 9fc4ea4c51b651b2
          readOnly: true
          description: |-
            Source of the configuration (business-specific or inherited from partner)

            * `business` - business
            * `partner` - partner
      required:
      - menu
      - source
    OAuth2ErrorResponse:
      type: object
      description: Serializer for OAuth2 error response
      properties:
        error:
          type: string
          description: Error code (e.g., 'invalid_client', 'unsupported_grant_type')
        error_description:
          type: string
          description: Human-readable error description
      required:
      - error
      - error_description
    OAuth2TokenRequestRequest:
      type: object
      description: Serializer for OAuth2 token request
      properties:
        grant_type:
          type: string
          minLength: 1
          default: client_credentials
          description: Must be 'client_credentials'
        client_id:
          type: string
          format: uuid
          description: Partner UUID (same as in Basic Auth username)
      required:
      - client_id
    OAuth2TokenResponse:
      type: object
      description: Serializer for OAuth2 token response
      properties:
        access_token:
          type: string
          description: JWT Bearer token for API authentication
        token_type:
          type: string
          default: Bearer
          description: Token type (always 'Bearer')
        expires_in:
          type: integer
          description: Token expiration time in seconds
      required:
      - access_token
      - expires_in
    OperatingActivities:
      type: object
      description: |-
        Operating Activities breakdown (Indirect Method).

        Starting with Net Profit, adjusts for:
        - Non-cash items (depreciation, amortisation)
        - Working capital changes (receivables, payables, inventory)
      properties:
        net_profit_cents:
          type: integer
          description: Net profit from P&L statement
        non_cash_adjustments:
          allOf:
          - $ref: '#/components/schemas/CashFlowSection'
          description: Non-cash expenses added back (depreciation, amortisation, etc.)
        working_capital_changes:
          allOf:
          - $ref: '#/components/schemas/CashFlowSection'
          description: Changes in current assets (excl. cash) and current liabilities
      required:
      - net_profit_cents
      - non_cash_adjustments
      - working_capital_changes
    PaginatedAccountingPeriodList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/AccountingPeriod'
    PaginatedBankAccountConnectionSummaryList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/BankAccountConnectionSummary'
    PaginatedBankTransactionCategoryGroupingResponseList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/BankTransactionCategoryGroupingResponse'
    PaginatedBankTransactionList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/BankTransaction'
    PaginatedBillList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/Bill'
    PaginatedBillPaymentListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/BillPaymentList'
    PaginatedBusinessListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/BusinessList'
    PaginatedChartOfAccountListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/ChartOfAccountList'
    PaginatedCustomerCreditList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/CustomerCredit'
    PaginatedCustomerList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/Customer'
    PaginatedFinancialBusinessListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/FinancialBusinessList'
    PaginatedFinancialDocumentList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/FinancialDocument'
    PaginatedInternalBusinessList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/InternalBusiness'
    PaginatedInternalPartnerList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/InternalPartner'
    PaginatedInternalUserList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/InternalUser'
    PaginatedInvoiceList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/Invoice'
    PaginatedInvoicePaymentListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/InvoicePaymentList'
    PaginatedJournalEntryListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/JournalEntryList'
    PaginatedPartnerBusinessListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/PartnerBusinessList'
    PaginatedPayoutListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/PayoutList'
    PaginatedPeriodOverviewItemList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/PeriodOverviewItem'
    PaginatedReceiptList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/Receipt'
    PaginatedRefundList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/Refund'
    PaginatedRefundPaymentList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/RefundPayment'
    PaginatedTaskList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/Task'
    PaginatedTaskListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/TaskList'
    PaginatedVendorCreditList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/VendorCredit'
    PaginatedVendorList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/Vendor'
    PaginatedVendorRefundList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/VendorRefund'
    PaginatedVendorRefundPaymentListList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/VendorRefundPaymentList'
    PaginatedWriteOffList:
      type: object
      required:
      - count
      - page_info
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of items
        page_info:
          type: object
          example:
            total_count: 123
            current_page: 1
            total_pages: 7
            page_size: 20
          required:
          - total_count
          - current_page
          - total_pages
          - page_size
          properties:
            total_count:
              type: integer
              example: 123
              description: Total number of items (same as count)
            current_page:
              type: integer
              example: 1
              description: Current page number (1-indexed)
            total_pages:
              type: integer
              example: 7
              description: Total number of pages
            page_size:
              type: integer
              example: 20
              description: Number of items per page
        results:
          type: array
          items:
            $ref: '#/components/schemas/WriteOff'
    PartnerAPIKey:
      type: object
      description: Serializer for partner API key (masked)
      properties:
        api_key:
          type: string
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        portal_enabled:
          type: boolean
          readOnly: true
        max_portal_users:
          type: integer
          readOnly: true
      required:
      - api_key
      - created_at
      - max_portal_users
      - portal_enabled
    PartnerAPIKeyRegenerate:
      type: object
      description: Serializer for API key regeneration response
      properties:
        api_key:
          type: string
          readOnly: true
        message:
          type: string
          readOnly: true
        regenerated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - api_key
      - message
      - regenerated_at
    PartnerAnalytics:
      type: object
      description: Serializer for partner analytics
      properties:
        total_businesses:
          type: integer
          readOnly: true
        active_businesses:
          type: integer
          readOnly: true
        total_portal_users:
          type: integer
          readOnly: true
      required:
      - active_businesses
      - total_businesses
      - total_portal_users
    PartnerBusinessDetail:
      type: object
      description: Detailed serializer for business in partner portal
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        legal_name:
          type: string
          readOnly: true
        external_id:
          type: string
          readOnly: true
        vat_number:
          type: string
          readOnly: true
        company_number:
          type: string
          readOnly: true
        tax_id:
          type: string
          readOnly: true
        business_type:
          type: string
          readOnly: true
          description: Business entity type. Validated against country-specific options
            for GB, DE, NL, ES, BE. Free text for other countries.
        country:
          enum:
          - GB
          - DE
          - FR
          - NL
          - ES
          - IT
          - IE
          - BE
          - AT
          - PT
          - SE
          - 'NO'
          - DK
          - FI
          - IS
          - MY
          - SG
          type: string
          description: |-
            * `GB` - United Kingdom
            * `DE` - Germany
            * `FR` - France
            * `NL` - Netherlands
            * `ES` - Spain
            * `IT` - Italy
            * `IE` - Ireland
            * `BE` - Belgium
            * `AT` - Austria
            * `PT` - Portugal
            * `SE` - Sweden
            * `NO` - Norway
            * `DK` - Denmark
            * `FI` - Finland
            * `IS` - Iceland
            * `MY` - Malaysia
            * `SG` - Singapore
          x-spec-enum-id: f4d5c691ea686889
          readOnly: true
        province:
          type: string
          readOnly: true
          description: Province or state within the country
        email:
          type: string
          format: email
          readOnly: true
        phone:
          type: string
          readOnly: true
        base_currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
          readOnly: true
        accounting_method:
          enum:
          - cash
          - accrual
          type: string
          description: |-
            * `cash` - Cash Basis
            * `accrual` - Accrual Basis
          x-spec-enum-id: 6f6d0e718e73bb81
          readOnly: true
        fiscal_year_end:
          type: string
          format: date
          readOnly: true
        ai_context:
          type: string
          readOnly: true
          description: Optional context for AI classification (what the business does,
            typical vendors/customers, revenue streams, cost structure, etc.).
        partner_metadata:
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - accounting_method
      - ai_context
      - base_currency
      - business_type
      - company_number
      - country
      - created_at
      - email
      - external_id
      - fiscal_year_end
      - id
      - is_active
      - legal_name
      - name
      - partner_metadata
      - phone
      - province
      - tax_id
      - updated_at
      - vat_number
    PartnerBusinessList:
      type: object
      description: Serializer for listing businesses in partner portal
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        legal_name:
          type: string
          readOnly: true
        external_id:
          type: string
          readOnly: true
        email:
          type: string
          format: email
          readOnly: true
        country:
          enum:
          - GB
          - DE
          - FR
          - NL
          - ES
          - IT
          - IE
          - BE
          - AT
          - PT
          - SE
          - 'NO'
          - DK
          - FI
          - IS
          - MY
          - SG
          type: string
          description: |-
            * `GB` - United Kingdom
            * `DE` - Germany
            * `FR` - France
            * `NL` - Netherlands
            * `ES` - Spain
            * `IT` - Italy
            * `IE` - Ireland
            * `BE` - Belgium
            * `AT` - Austria
            * `PT` - Portugal
            * `SE` - Sweden
            * `NO` - Norway
            * `DK` - Denmark
            * `FI` - Finland
            * `IS` - Iceland
            * `MY` - Malaysia
            * `SG` - Singapore
          x-spec-enum-id: f4d5c691ea686889
          readOnly: true
        base_currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
          readOnly: true
        is_active:
          type: boolean
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - base_currency
      - country
      - created_at
      - email
      - external_id
      - id
      - is_active
      - legal_name
      - name
      - updated_at
    PartnerPortalLoginRequest:
      type: object
      description: Serializer for partner portal login requests
      properties:
        email:
          type: string
          format: email
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 1
      required:
      - email
      - password
    PartnerPortalToken:
      type: object
      description: Serializer for partner portal token responses
      properties:
        access_token:
          type: string
        expires_in:
          type: integer
        token_type:
          type: string
        user:
          type: object
          additionalProperties: {}
          nullable: true
          readOnly: true
      required:
      - access_token
      - expires_in
      - token_type
      - user
    PatchedAccountUpdateAPIRequest:
      type: object
      description: |-
        Serializer for partial updates to accounts (PATCH only).

        Non-editable fields: code, account_type (if transactions exist).
        Supports moving accounts in hierarchy via parent_id.
      properties:
        name:
          type: string
          description: Custom display name for the account
          maxLength: 255
        description:
          type: string
          description: Account description
        parent_id:
          type: string
          nullable: true
          description: Parent account identifier (UUID, code, or external_id). Set
            to null to make root account.
        is_active:
          type: boolean
          description: Whether account is active. Set to false to deactivate.
        institution_name:
          type: string
          maxLength: 255
        iban:
          type: string
          maxLength: 34
        sort_code:
          type: string
          maxLength: 8
        account_number_mask:
          type: string
          maxLength: 20
        balance_behavior:
          enum:
          - ''
          - debit_positive
          - credit_positive
          type: string
          description: |-
            * `` - Auto-detect
            * `debit_positive` - Debit Positive
            * `credit_positive` - Credit Positive
          x-spec-enum-id: 3fa8710cd3575d95
        is_cash_account:
          type: boolean
        is_non_cash_expense:
          type: boolean
        custom_fields: {}
    PatchedBillPaymentUpdateRequest:
      type: object
      description: |-
        Serializer for updating bill payment status and details.

        Allows updating payment metadata, references, status transitions, and allocations.
      properties:
        status:
          enum:
          - pending
          - processing
          - completed
          - failed
          - cancelled
          type: string
          x-spec-enum-id: 13b0995e5c712ee4
          description: |-
            Updated payment status (pending, processing, completed, failed, cancelled)

            * `pending` - pending
            * `processing` - processing
            * `completed` - completed
            * `failed` - failed
            * `cancelled` - cancelled
        failure_reason:
          type: string
          description: Reason for failure (required when status=failed)
        payment_reference:
          type: string
          description: Updated payment reference
          maxLength: 100
        check_number:
          type: string
          description: Updated check number
          maxLength: 50
        description:
          type: string
          description: Updated payment description
        memo:
          type: string
          description: Updated memo or notes
        processing_fee_cents:
          type: integer
          minimum: 0
          description: Updated processing fee in cents
        metadata:
          description: Updated custom key-value pairs
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/BillPaymentAllocationRequest'
          description: Updated bill allocations (replaces existing allocations)
    PatchedFinancialPortalTaskUpdateRequest:
      type: object
      description: |-
        Serializer for updating tasks from Financial Admin Portal.

        Only allows updating certain fields.
      properties:
        title:
          type: string
          minLength: 1
          description: Task title
          maxLength: 255
        description:
          type: string
          description: Task description
        due_date:
          type: string
          format: date
          nullable: true
          description: Task due date
        status:
          enum:
          - pending_response
          - in_review
          type: string
          x-spec-enum-id: 9b22beba9b658be0
          description: |-
            Task status (limited options)

            * `pending_response` - pending_response
            * `in_review` - in_review
    PatchedFixedAssetRequest:
      type: object
      description: |-
        Fixed Asset serializer with auto-population.

        Auto-populates:
        - useful_life_months from country config (if not provided)
        - depreciation_start_date (calculated on save)
        - asset_number (generated on save)
      properties:
        business:
          type: string
          format: uuid
        description:
          type: string
          minLength: 1
          description: Asset description (e.g., 'MacBook Pro 16-inch 2024')
          maxLength: 255
        category:
          enum:
          - computer_equipment
          - office_furniture
          - vehicles
          - machinery
          - buildings
          - leasehold_improvements
          - software
          - other
          type: string
          x-spec-enum-id: 853bec44a2bd14ca
          description: |-
            Asset category for grouping and reporting

            * `computer_equipment` - Computer Equipment
            * `office_furniture` - Office Furniture & Equipment
            * `vehicles` - Vehicles
            * `machinery` - Machinery & Equipment
            * `buildings` - Buildings
            * `leasehold_improvements` - Leasehold Improvements
            * `software` - Software & Licenses
            * `other` - Other Fixed Assets
        acquisition_date:
          type: string
          format: date
          description: Date asset was acquired/put into service
        supplier:
          type: string
          description: Supplier/vendor name (optional)
          maxLength: 255
        acquisition_cost_cents:
          type: integer
          minimum: 0
          writeOnly: true
          description: Acquisition cost in cents
        residual_value_cents:
          type: integer
          minimum: 0
          writeOnly: true
          description: Residual value in cents
        depreciation_method:
          enum:
          - straight_line
          - declining_balance
          type: string
          x-spec-enum-id: 0208219e8247f3d3
          description: |-
            Depreciation method

            * `straight_line` - Straight-Line
            * `declining_balance` - Declining Balance
        useful_life_months:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          description: Expected useful life in months
        asset_account:
          type: string
          format: uuid
          description: GL account for asset cost (e.g., 1700)
        accumulated_depreciation_account:
          type: string
          format: uuid
          description: Contra-asset account for accumulated depreciation (e.g., 1710)
        depreciation_expense_account:
          type: string
          format: uuid
          description: P&L account for depreciation expense
        location:
          type: string
          description: Physical location or department
          maxLength: 255
        serial_number:
          type: string
          description: Manufacturer serial number
          maxLength: 100
        metadata:
          description: Extensible field for custom attributes
        external_id:
          type: string
          description: External system identifier
          maxLength: 100
        created_by:
          type: string
          description: User who created the asset
          maxLength: 100
    PatchedRefundUpdateRequest:
      type: object
      description: Serializer for updating refunds with optional document upload.
      properties:
        memo:
          type: string
          description: Description or reason for the refund
        reference_number:
          type: string
          description: Reference number for tracking
          maxLength: 100
        metadata:
          nullable: true
          description: Custom key-value pairs
        document:
          allOf:
          - $ref: '#/components/schemas/RefundDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    PatchedTaskMessageUpdateRequest:
      type: object
      description: Serializer for updating TaskMessage with multiple document upload
        support.
      properties:
        message:
          type: string
          minLength: 1
        metadata: {}
        documents:
          type: array
          items:
            $ref: '#/components/schemas/TaskMessageDocumentUploadRequest'
          writeOnly: true
          description: Optional list of document uploads (max 10 files per request).
          maxItems: 10
    PatchedTaskRequest:
      type: object
      description: |-
        Serializer for Task model with related entity details.

        Provides task information for business owners including:
        - Task metadata (title, description, status)
        - Submission state (has_submission, current_submission)
        - Rejection information when applicable
        - Linked entity details (transaction, invoice, bill)
      properties:
        title:
          type: string
          minLength: 1
          description: 'Short title describing the task. Example: ''Missing receipt
            for Office Depot'''
        description:
          type: string
          minLength: 1
          description: 'Detailed description or question from the bookkeeper. Example:
            ''Please provide the receipt for €250 charge on Jan 6, 2025.'''
        status:
          enum:
          - pending_response
          - in_review
          - closed
          type: string
          x-spec-enum-id: ea18c01c61dd6cc1
          description: |-
            Current task status: pending_response (waiting for owner), in_review (bookkeeper reviewing), closed (completed)

            * `pending_response` - Pending Response
            * `in_review` - In Review
            * `closed` - Closed
        accounting_period:
          type: string
          format: uuid
          nullable: true
          description: Associated accounting period for monthly grouping
        created_by:
          type: string
          format: uuid
          nullable: true
        closed_by:
          type: string
          format: uuid
          nullable: true
        due_date:
          type: string
          format: date
          nullable: true
          description: 'Optional due date for task completion. Format: YYYY-MM-DD.
            Example: ''2025-01-15'''
        metadata: {}
    PatchedTransactionCategorizationRequestRequest:
      type: object
      description: |-
        Serializer for transaction categorization requests.
        Handles manual categorization with new subcategory_id structure.
      properties:
        subcategory_id:
          type: string
          format: uuid
          description: UUID of the transaction subcategory
        description_override:
          type: string
          description: Optional description override for the transaction
          maxLength: 500
        counterparty_name_override:
          type: string
          description: Optional counterparty name override
          maxLength: 200
        categorization_status:
          enum:
          - pending
          - categorized
          - manual_review
          - approved
          - ''
          type: string
          x-spec-enum-id: af30d82e198cc7fb
          description: |-
            Optional categorization status override

            * `pending` - Pending Review
            * `categorized` - AI Categorized
            * `manual_review` - Requires Manual Review
            * `approved` - Approved
    PatchedUpdateBusinessRequest:
      type: object
      description: Serializer for updating existing businesses
      properties:
        legal_name:
          type: string
          minLength: 1
          description: Legal registered name of the business
          maxLength: 255
        entity_type:
          type: string
          description: Business entity type (e.g., 'limited', 'gmbh', 'bv')
        phone_number:
          type: string
          description: Business phone number
        tin:
          type: string
          description: Tax identification number (other than VAT)
        vat_number:
          type: string
          description: EU VAT registration number
          maxLength: 20
        company_number:
          type: string
          description: Company registration number (e.g., Companies House number for
            UK)
          maxLength: 20
        province:
          type: string
          description: Province or state within the country
          maxLength: 100
        eu_nace_industry_code:
          type: string
          description: European NACE industry classification code
          maxLength: 10
        email:
          type: string
          format: email
          minLength: 1
          description: Primary email address for the business
        accounting_method:
          enum:
          - cash
          - accrual
          type: string
          x-spec-enum-id: 6f6d0e718e73bb81
          description: |-
            Accounting method: 'cash' or 'accrual'

            * `cash` - Cash Basis
            * `accrual` - Accrual Basis
        fiscal_year_end:
          type: string
          format: date
          description: 'Fiscal year end date (format: YYYY-MM-DD)'
        metadata:
          description: Custom JSON metadata for partner-specific data
    PatchedUpdatePaymentRequest:
      type: object
      description: |-
        Serializer for updating existing payments.
        Matches the create endpoint structure (InvoiceRecordPaymentRequestSerializer)
        to provide consistency between create and update APIs.
      properties:
        customer_id:
          type: string
          format: uuid
          description: Customer UUID (cannot be changed after creation)
        total_amount_cents:
          type: integer
          minimum: 1
          description: Updated total payment amount in cents (must not be less than
            allocated amount)
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/PaymentAllocationUpdateRequest'
          description: Updated list of invoice allocations (replaces existing allocations)
        payment_date:
          type: string
          format: date
          description: 'Updated payment date (ISO date format: YYYY-MM-DD)'
        currency:
          type: string
          minLength: 1
          description: Payment currency (cannot be changed after creation)
          maxLength: 3
        payment_method:
          enum:
          - bank_transfer
          - credit_card
          - debit_card
          - ach
          - check
          - cash
          - paypal
          - stripe
          - other
          type: string
          x-spec-enum-id: 1a9252035ec0bc4a
          description: |-
            Updated payment method (bank_transfer, card, cash, cheque, direct_debit)

            * `bank_transfer` - bank_transfer
            * `credit_card` - credit_card
            * `debit_card` - debit_card
            * `ach` - ach
            * `check` - check
            * `cash` - cash
            * `paypal` - paypal
            * `stripe` - stripe
            * `other` - other
        payment_reference:
          type: string
          description: Updated internal payment reference
        external_id:
          type: string
          description: Updated external identifier (must remain unique)
        note:
          type: string
          description: Updated internal notes or description
        notes:
          type: string
          description: Legacy field for notes (use 'note' instead)
        metadata:
          type: object
          additionalProperties: {}
          description: Updated custom key-value pairs
        references:
          type: object
          additionalProperties:
            type: string
          description: Updated payment references (bank_reference, end_to_end_id,
            payment_reference)
        processor_reference:
          type: string
          description: Updated payment processor reference
          maxLength: 255
        bank_reference:
          type: string
          description: Updated bank transaction reference
          maxLength: 100
        status:
          enum:
          - pending
          - processing
          - completed
          - failed
          - cancelled
          - refunded
          type: string
          x-spec-enum-id: 760241f0a4b58134
          description: |-
            Updated payment status (pending, processing, completed, failed, cancelled, refunded)

            * `pending` - Pending
            * `processing` - Processing
            * `completed` - Completed
            * `failed` - Failed
            * `cancelled` - Cancelled
            * `refunded` - Refunded
        transaction_tags:
          type: array
          items:
            type: string
            minLength: 1
          description: Updated tags for categorization
        payment_processor:
          type: string
          description: Updated payment processor name
          maxLength: 100
        processing_fee_cents:
          type: integer
          minimum: 0
          description: Updated processing fee in cents
    PatchedVendorRefundPaymentUpdateRequest:
      type: object
      description: Serializer for updating vendor refund payment status and details.
      properties:
        status:
          enum:
          - pending
          - processing
          - completed
          - failed
          - cancelled
          type: string
          x-spec-enum-id: 13b0995e5c712ee4
          description: |-
            New payment status

            * `pending` - pending
            * `processing` - processing
            * `completed` - completed
            * `failed` - failed
            * `cancelled` - cancelled
        failure_reason:
          type: string
          description: Reason for failure (required if status is 'failed')
        payment_reference:
          type: string
          description: Updated payment reference
          maxLength: 100
        memo:
          type: string
          description: Updated memo
        metadata:
          nullable: true
          description: Updated metadata
    PatchedVendorRefundUpdateRequest:
      type: object
      description: Serializer for updating vendor refunds with optional document upload.
      properties:
        description:
          type: string
        memo:
          type: string
        reason:
          type: string
          maxLength: 500
        metadata:
          nullable: true
        expected_completion_date:
          type: string
          format: date
          nullable: true
        document:
          allOf:
          - $ref: '#/components/schemas/VendorRefundDocumentUploadRequest'
          writeOnly: true
    PaymentAllocationItemRequest:
      type: object
      description: Nested serializer for payment allocation items
      properties:
        invoice_id:
          type: string
          format: uuid
          description: UUID of the invoice to allocate payment to
        amount_cents:
          type: integer
          minimum: 1
          description: Amount in cents to allocate to this invoice (cannot exceed
            invoice outstanding balance)
      required:
      - amount_cents
      - invoice_id
    PaymentAllocationUpdateRequest:
      type: object
      description: Serializer for payment allocations in updates (matches create endpoint
        structure)
      properties:
        invoice_id:
          type: string
          format: uuid
          description: UUID of the invoice to allocate payment to
        amount_cents:
          type: integer
          minimum: 1
          description: Amount in cents to allocate to this invoice
      required:
      - amount_cents
      - invoice_id
    PaymentCreateResponse:
      type: object
      description: Response serializer for create invoice payment endpoint
      properties:
        payment:
          $ref: '#/components/schemas/PaymentDetail'
      required:
      - payment
    PaymentDetail:
      type: object
      description: Detailed payment information in response - all amounts in cents
      properties:
        id:
          type: string
          format: uuid
          description: Unique payment identifier
        business_id:
          type: string
          format: uuid
          description: Business this payment belongs to
        customer_id:
          type: string
          format: uuid
          description: Customer who made the payment
        total_amount_cents:
          type: integer
          description: Total payment amount in cents
        applied_amount_cents:
          type: integer
          description: Amount applied to invoices in cents
        allocated_amount_cents:
          type: integer
          description: Amount allocated to invoices in cents
        unapplied_amount_cents:
          type: integer
          description: Unapplied amount remaining in cents
        remaining_amount_cents:
          type: integer
          description: Remaining unallocated amount in cents
        currency:
          type: string
          description: Payment currency (e.g., GBP, EUR, USD)
        status:
          type: string
          description: Payment status (pending, processing, completed, failed, cancelled,
            refunded)
        payment_method:
          type: string
          description: Payment method (bank_transfer, card, etc.)
        payment_reference:
          type: string
          description: Your internal payment reference
        external_id:
          type: string
          description: Your unique external identifier
        note:
          type: string
          description: Internal note or description
        notes:
          type: string
          description: Legacy notes field
        bank_reference:
          type: string
          description: Bank transaction reference
        metadata:
          type: object
          additionalProperties: {}
          description: Custom key-value pairs
        idempotency_key:
          type: string
          description: Idempotency key if provided
        created_at:
          type: string
          format: date-time
          description: Payment creation timestamp
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp
        payouts:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Payout information if applicable
        applied_invoices:
          type: array
          items:
            $ref: '#/components/schemas/PaymentInvoiceDetail'
          description: Invoices this payment was applied to
      required:
      - allocated_amount_cents
      - applied_amount_cents
      - applied_invoices
      - business_id
      - created_at
      - currency
      - customer_id
      - id
      - payment_method
      - remaining_amount_cents
      - status
      - total_amount_cents
      - unapplied_amount_cents
      - updated_at
    PaymentInvoiceDetail:
      type: object
      description: Invoice details in payment response - all amounts in cents
      properties:
        id:
          type: string
          format: uuid
          description: Invoice UUID
        invoice_number:
          type: string
          description: Invoice number (e.g., INV-0042)
        applied_amount_cents:
          type: integer
          description: Amount applied to this invoice in cents
        status:
          type: string
          description: Invoice status after payment (sent, paid, overdue, etc.)
        outstanding_amount_cents:
          type: integer
          description: Remaining outstanding balance on invoice in cents
      required:
      - applied_amount_cents
      - id
      - outstanding_amount_cents
      - status
    PaymentRefundAllocationSummary:
      type: object
      description: Refund allocation summary for payment detail view - shows refunds
        that used this payment.
      properties:
        refund_id:
          type: string
          format: uuid
        reference_number:
          type: string
        amount_cents:
          type: integer
        allocated_at:
          type: string
          format: date-time
      required:
      - allocated_at
      - amount_cents
      - refund_id
    PayoutCreateRequest:
      type: object
      description: |-
        Serializer for creating or updating payouts
        All amounts in cents (integers)
      properties:
        external_id:
          type: string
          minLength: 1
          description: Partner's unique payout ID (idempotency key)
          maxLength: 255
        processor:
          enum:
          - stripe
          - paypal
          - square
          - adyen
          - worldpay
          - sage_pay
          - klarna
          - other
          type: string
          x-spec-enum-id: 2e3f3dccc08fb43f
          description: |-
            Payment processor (stripe, adyen, paypal, etc.)

            * `stripe` - Stripe
            * `paypal` - PayPal
            * `square` - Square
            * `adyen` - Adyen
            * `worldpay` - Worldpay
            * `sage_pay` - Sage Pay
            * `klarna` - Klarna
            * `other` - Other
        processor_payout_id:
          type: string
          description: Processor's payout ID reference
          maxLength: 255
        paid_out_amount_cents:
          type: integer
          description: Net payout amount in cents (can be negative if refunds exceed
            payments)
        fee_cents:
          type: integer
          minimum: 0
          description: Processor fee charged in cents (must be >= 0)
        additional_refunds_amount_cents:
          type: integer
          minimum: 0
          default: 0
          description: Additional refunds not tied to specific RefundPayment records
            in cents
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          x-spec-enum-id: afe366a2ba7f6cae
          description: |-
            Payout currency (ISO 4217)

            * `EUR` - EUR
            * `GBP` - GBP
            * `USD` - USD
            * `SEK` - SEK
            * `NOK` - NOK
            * `DKK` - DKK
            * `ISK` - ISK
            * `MYR` - MYR
            * `SGD` - SGD
        status:
          enum:
          - pending
          - processing
          - paid
          - failed
          - cancelled
          type: string
          x-spec-enum-id: c671b6dd1cffeef4
          description: |-
            Payout status (must be 'paid')

            * `pending` - Pending
            * `processing` - Processing
            * `paid` - Paid
            * `failed` - Failed
            * `cancelled` - Cancelled
        completed_at:
          type: string
          format: date-time
          description: When payout was completed (ISO 8601)
        payment_ids:
          type: array
          items:
            type: string
            format: uuid
          description: List of Payment UUIDs included in this payout
        refund_payment_ids:
          type: array
          items:
            type: string
            format: uuid
          description: List of RefundPayment UUIDs included in this payout
        reference_number:
          type: string
          description: User-visible payout reference number
          maxLength: 100
        memo:
          type: string
          description: Internal memo or notes
        metadata:
          description: Custom metadata (max 1KB JSON object)
      required:
      - completed_at
      - currency
      - external_id
      - fee_cents
      - paid_out_amount_cents
      - processor
      - status
    PayoutList:
      type: object
      description: |-
        Simplified payout serializer for list views
        Excludes expanded payment/refund arrays for performance
        Shows only counts and totals
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        business_id:
          type: string
          format: uuid
          readOnly: true
        external_id:
          type: string
          maxLength: 255
        processor:
          enum:
          - stripe
          - paypal
          - square
          - adyen
          - worldpay
          - sage_pay
          - klarna
          - other
          - ''
          type: string
          description: |-
            * `stripe` - Stripe
            * `paypal` - PayPal
            * `square` - Square
            * `adyen` - Adyen
            * `worldpay` - Worldpay
            * `sage_pay` - Sage Pay
            * `klarna` - Klarna
            * `other` - Other
          x-spec-enum-id: 2e3f3dccc08fb43f
        processor_payout_id:
          type: string
          maxLength: 255
        paid_out_amount_cents:
          type: integer
          maximum: 9223372036854775807
          minimum: -9223372036854775808
          format: int64
          description: Net payout amount in cents (can be negative)
        fee_cents:
          type: integer
          maximum: 9223372036854775807
          minimum: 0
          format: int64
        additional_refunds_amount_cents:
          type: integer
          maximum: 9223372036854775807
          minimum: 0
          format: int64
          description: Additional refunds not tied to specific RefundPayment records
        net_amount_cents:
          type: integer
          readOnly: true
          description: 'Net amount: paid_out_amount - fee'
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
        status:
          enum:
          - pending
          - processing
          - paid
          - failed
          - cancelled
          type: string
          description: |-
            * `pending` - Pending
            * `processing` - Processing
            * `paid` - Paid
            * `failed` - Failed
            * `cancelled` - Cancelled
          x-spec-enum-id: c671b6dd1cffeef4
        completed_at:
          type: string
          format: date-time
          nullable: true
        imported_at:
          type: string
          format: date-time
          readOnly: true
        reference_number:
          type: string
          maxLength: 100
        memo:
          type: string
        payment_count:
          type: integer
          description: Number of payments in this payout
          readOnly: true
        refund_payment_count:
          type: integer
          description: Number of refund payments in this payout
          readOnly: true
        gross_payments_amount_cents:
          type: integer
          description: Total amount of invoice payments before refunds
          readOnly: true
        total_refunds_amount_cents:
          type: integer
          description: Total amount of refund payments in cents
          readOnly: true
        expected_net_amount_cents:
          type: integer
          description: 'Expected net: payments - refunds - additional_refunds - fees'
          readOnly: true
        amount_variance_cents:
          type: integer
          description: Difference between reported and expected net
          readOnly: true
        reconciliation_status:
          enum:
          - unreconciled
          - partially_reconciled
          - fully_reconciled
          type: string
          x-spec-enum-id: 0d688bdcecae9270
          readOnly: true
          description: |-
            Reconciliation state

            * `unreconciled` - Unreconciled
            * `partially_reconciled` - Partially Reconciled
            * `fully_reconciled` - Fully Reconciled
        settlement_file_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: Settlement file UUID if attached
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - amount_variance_cents
      - business_id
      - created_at
      - expected_net_amount_cents
      - gross_payments_amount_cents
      - id
      - imported_at
      - net_amount_cents
      - paid_out_amount_cents
      - payment_count
      - processor
      - processor_payout_id
      - reconciliation_status
      - refund_payment_count
      - settlement_file_id
      - total_refunds_amount_cents
      - updated_at
    PayoutResponse:
      type: object
      description: |-
        Full payout serializer for detail views and create responses
        Includes all computed fields and expanded payment/refund arrays
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        business_id:
          type: string
          format: uuid
          readOnly: true
        external_id:
          type: string
          maxLength: 255
        processor:
          enum:
          - stripe
          - paypal
          - square
          - adyen
          - worldpay
          - sage_pay
          - klarna
          - other
          - ''
          type: string
          description: |-
            * `stripe` - Stripe
            * `paypal` - PayPal
            * `square` - Square
            * `adyen` - Adyen
            * `worldpay` - Worldpay
            * `sage_pay` - Sage Pay
            * `klarna` - Klarna
            * `other` - Other
          x-spec-enum-id: 2e3f3dccc08fb43f
        processor_payout_id:
          type: string
          maxLength: 255
        paid_out_amount_cents:
          type: integer
          maximum: 9223372036854775807
          minimum: -9223372036854775808
          format: int64
          description: Net payout amount in cents (can be negative)
        fee_cents:
          type: integer
          maximum: 9223372036854775807
          minimum: 0
          format: int64
        additional_refunds_amount_cents:
          type: integer
          maximum: 9223372036854775807
          minimum: 0
          format: int64
          description: Additional refunds not tied to specific RefundPayment records
        net_amount_cents:
          type: integer
          readOnly: true
          description: 'Net amount: paid_out_amount - fee'
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
        status:
          enum:
          - pending
          - processing
          - paid
          - failed
          - cancelled
          type: string
          description: |-
            * `pending` - Pending
            * `processing` - Processing
            * `paid` - Paid
            * `failed` - Failed
            * `cancelled` - Cancelled
          x-spec-enum-id: c671b6dd1cffeef4
        completed_at:
          type: string
          format: date-time
          nullable: true
        imported_at:
          type: string
          format: date-time
          readOnly: true
        reference_number:
          type: string
          maxLength: 100
        memo:
          type: string
        metadata: {}
        payment_count:
          type: integer
          description: Number of payments in this payout
          readOnly: true
        refund_payment_count:
          type: integer
          description: Number of refund payments in this payout
          readOnly: true
        gross_payments_amount_cents:
          type: integer
          description: Total amount of invoice payments before refunds
          readOnly: true
        total_refunds_amount_cents:
          type: integer
          description: Total amount of refund payments in cents
          readOnly: true
        expected_net_amount_cents:
          type: integer
          description: 'Expected net: payments - refunds - additional_refunds - fees'
          readOnly: true
        amount_variance_cents:
          type: integer
          description: Difference between reported and expected net (for debugging)
          readOnly: true
        payments:
          type: array
          items: {}
          description: Expanded payment details
          readOnly: true
        refund_payments:
          type: array
          items: {}
          description: Expanded refund payment details
          readOnly: true
        reconciliation_status:
          enum:
          - unreconciled
          - partially_reconciled
          - fully_reconciled
          type: string
          x-spec-enum-id: 0d688bdcecae9270
          readOnly: true
          description: |-
            Reconciliation state

            * `unreconciled` - Unreconciled
            * `partially_reconciled` - Partially Reconciled
            * `fully_reconciled` - Fully Reconciled
        settlement_file_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: Settlement file UUID if attached
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - amount_variance_cents
      - business_id
      - created_at
      - expected_net_amount_cents
      - gross_payments_amount_cents
      - id
      - imported_at
      - net_amount_cents
      - paid_out_amount_cents
      - payment_count
      - payments
      - processor
      - processor_payout_id
      - reconciliation_status
      - refund_payment_count
      - refund_payments
      - settlement_file_id
      - total_refunds_amount_cents
      - updated_at
    PeriodCloseChecklist:
      type: object
      description: Serializer for period close checklist response
      properties:
        period_id:
          type: string
          format: uuid
        period_name:
          type: string
        can_close:
          type: boolean
        checks:
          type: array
          items:
            $ref: '#/components/schemas/CheckDetail'
        warnings:
          type: array
          items:
            type: string
        blockers:
          type: array
          items:
            type: string
        note:
          type: string
        summary:
          type: object
          additionalProperties: {}
      required:
      - blockers
      - can_close
      - checks
      - note
      - period_id
      - period_name
      - summary
      - warnings
    PeriodCloseRequest:
      type: object
      description: Serializer for closing a period
      properties:
        closed_by:
          type: string
        reason:
          type: string
    PeriodCloseResponse:
      type: object
      description: Serializer for period close response (period + checklist)
      properties:
        period:
          $ref: '#/components/schemas/AccountingPeriod'
        checklist:
          $ref: '#/components/schemas/PeriodCloseChecklist'
      required:
      - checklist
      - period
    PeriodCreateRequest:
      type: object
      description: Serializer for creating a new accounting period
      properties:
        business_id:
          type: string
          format: uuid
        year:
          type: integer
          maximum: 2100
          minimum: 2000
        month:
          type: integer
          maximum: 12
          minimum: 1
      required:
      - business_id
      - month
      - year
    PeriodOverviewItem:
      type: object
      description: |-
        Serializer for period overview response items.
        Used for Swagger documentation of the period_overview endpoint.
      properties:
        year:
          type: integer
          description: Year number
        month:
          type: integer
          description: Month number (1-12)
        period_name:
          type: string
          description: Display name (e.g., '2025-01')
        period_id:
          type: string
          format: uuid
          description: UUID of the accounting period
        pending_count:
          type: integer
          description: Tasks waiting for owner response
        in_review_count:
          type: integer
          description: Tasks submitted, waiting for bookkeeper
        has_pending_tasks:
          type: boolean
          description: True if pending_count > 0
      required:
      - has_pending_tasks
      - in_review_count
      - month
      - pending_count
      - period_id
      - period_name
      - year
    PeriodReopenRequest:
      type: object
      description: Serializer for reopening a period
      properties:
        reopened_by:
          type: string
        reason:
          type: string
    PeriodReopenResponse:
      type: object
      description: Serializer for period reopen response
      properties:
        period:
          $ref: '#/components/schemas/AccountingPeriod'
        message:
          type: string
      required:
      - message
      - period
    PeriodTrend:
      type: object
      description: |-
        Financial metrics for a single period.

        Used in the trends array to show revenue, expenses, and profit per period.
      properties:
        period_start:
          type: string
          format: date
          description: Period start date
        period_end:
          type: string
          format: date
          description: Period end date
        revenue_cents:
          type: integer
          description: Total revenue for this period in cents
        expenses_cents:
          type: integer
          description: Total expenses for this period in cents
        net_profit_cents:
          type: integer
          description: Net profit for this period in cents
      required:
      - expenses_cents
      - net_profit_cents
      - period_end
      - period_start
      - revenue_cents
    PricingInquiryCreateRequest:
      type: object
      description: Request serializer for submitting a pricing inquiry.
      properties:
        partner_id:
          type: string
          format: uuid
          description: UUID of the partner
        business_name:
          type: string
          minLength: 1
          description: Name of the business requesting pricing
          maxLength: 255
        person_name:
          type: string
          minLength: 1
          description: Contact person's full name
          maxLength: 255
        email:
          type: string
          format: email
          minLength: 1
          description: Contact email address
        phone:
          type: string
          description: Contact phone number (optional)
          maxLength: 50
        country_code:
          type: string
          minLength: 2
          description: ISO 3166-1 country code (e.g., 'NL', 'US', 'GB', 'USA')
          maxLength: 3
        selected_tier:
          type: string
          minLength: 1
          description: Selected pricing tier (e.g., 'tier_1', 'tier_2', 'tier_3')
          maxLength: 50
        bookkeeping_included:
          type: boolean
          default: false
          description: 'Whether bookkeeping services are requested (default: false)'
      required:
      - business_name
      - country_code
      - email
      - partner_id
      - person_name
      - selected_tier
    PricingInquiryResponse:
      type: object
      description: Response serializer for pricing inquiry creation.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the inquiry
        status:
          type: string
          description: Current status of the inquiry
        message:
          type: string
          description: Confirmation message
      required:
      - id
      - message
      - status
    PricingTierResponse:
      type: object
      description: Serializer for a single pricing tier in response.
      properties:
        name:
          type: string
          description: Tier identifier (e.g., 'tier_1', 'tier_2')
        display_order:
          type: integer
          description: Display order for frontend sorting (1, 2, 3, ...)
        transactions_per_month:
          type: integer
          nullable: true
          description: Maximum transactions per month (null = unlimited)
        price_cents:
          type: integer
          description: Price in cents (e.g., 1900 = 19.00)
        price_display:
          type: string
          description: Formatted price for display (e.g., '19.00')
          readOnly: true
      required:
      - display_order
      - name
      - price_cents
      - price_display
      - transactions_per_month
    PricingTiersRequestRequest:
      type: object
      description: Request serializer for fetching pricing tiers.
      properties:
        partner_id:
          type: string
          format: uuid
          description: UUID of the partner to fetch pricing for
        business_name:
          type: string
          minLength: 1
          description: Optional business name for context
          maxLength: 255
      required:
      - partner_id
    PricingTiersResponse:
      type: object
      description: Response serializer for pricing tiers endpoint.
      properties:
        currency:
          type: string
          description: Currency code (e.g., 'EUR', 'USD')
        tiers:
          type: array
          items:
            $ref: '#/components/schemas/PricingTierResponse'
          description: List of available pricing tiers
      required:
      - currency
      - tiers
    ProfitAndLoss:
      type: object
      description: |-
        Complete P&L report response.

        Subtype group keys are AccountSubtype.value:
        - "revenue" (from Account.AccountSubtype.REVENUE.value)
        - "other_operating_income" (from Account.AccountSubtype.OTHER_OPERATING_INCOME.value)
        - etc.
      properties:
        business_id:
          type: string
          format: uuid
          description: Business UUID
        start_date:
          type: string
          format: date
          description: Report period start
        end_date:
          type: string
          format: date
          description: Report period end
        currency:
          type: string
          description: Business base currency
        detail_level:
          enum:
          - summary
          - detailed
          type: string
          x-spec-enum-id: 42d5883c5aa0b3a9
          description: |-
            'summary' or 'detailed'

            * `summary` - summary
            * `detailed` - detailed
        summary:
          allOf:
          - $ref: '#/components/schemas/ProfitAndLossSummary'
          description: Calculated P&L totals
        revenue:
          $ref: '#/components/schemas/SubtypeGroup'
        other_operating_income:
          $ref: '#/components/schemas/SubtypeGroup'
        direct_costs:
          $ref: '#/components/schemas/SubtypeGroup'
        operating_expenses:
          $ref: '#/components/schemas/SubtypeGroup'
        finance_income:
          $ref: '#/components/schemas/SubtypeGroup'
        finance_costs:
          $ref: '#/components/schemas/SubtypeGroup'
        income_tax:
          $ref: '#/components/schemas/SubtypeGroup'
      required:
      - business_id
      - currency
      - detail_level
      - end_date
      - start_date
      - summary
    ProfitAndLossSummary:
      type: object
      description: |-
        Calculated P&L totals.

        Each field is calculated from AccountSubtype totals:
        - net_revenue_cents = Sum of REVENUE subtype
        - total_operating_income_cents = net_revenue + OTHER_OPERATING_INCOME
        - gross_profit_cents = total_operating_income - DIRECT_COSTS
        - operating_profit_cents = gross_profit - OPERATING_EXPENSES
        - profit_before_tax_cents = operating_profit + FINANCE_INCOME - FINANCE_COSTS
        - net_profit_cents = profit_before_tax - INCOME_TAX
      properties:
        net_revenue_cents:
          type: integer
          description: Sum of AccountSubtype.REVENUE
        total_operating_income_cents:
          type: integer
          description: Net revenue + OTHER_OPERATING_INCOME
        gross_profit_cents:
          type: integer
          description: Total operating income - DIRECT_COSTS
        total_operating_expenses_cents:
          type: integer
          description: Sum of AccountSubtype.OPERATING_EXPENSES
        operating_profit_cents:
          type: integer
          description: Gross profit - OPERATING_EXPENSES
        profit_before_tax_cents:
          type: integer
          description: Operating profit + FINANCE_INCOME - FINANCE_COSTS
        net_profit_cents:
          type: integer
          description: Profit before tax - INCOME_TAX
      required:
      - gross_profit_cents
      - net_profit_cents
      - net_revenue_cents
      - operating_profit_cents
      - profit_before_tax_cents
      - total_operating_expenses_cents
      - total_operating_income_cents
    Receipt:
      type: object
      description: Main receipt serializer for list/fetch responses, aligned with
        Bill API style
      properties:
        type:
          type: string
          readOnly: true
        id:
          type: string
          format: uuid
          readOnly: true
        business_id:
          type: string
          format: uuid
          readOnly: true
        external_id:
          type: string
        receipt_number:
          type: string
        receipt_date:
          type: string
          format: date-time
          readOnly: true
        description:
          type: string
        payment_method:
          type: string
        metadata: {}
        currency:
          type: string
          readOnly: true
        vendor:
          allOf:
          - $ref: '#/components/schemas/Vendor'
          readOnly: true
        document:
          allOf:
          - $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: Receipt document with presigned URL (retrieve only)
        total_amount:
          type: integer
          description: Total receipt amount in cents
          readOnly: true
        reconciled_bank_transactions:
          type: array
          items:
            $ref: '#/components/schemas/EntityReconciliationDetail'
          readOnly: true
          description: Bank transactions this receipt is reconciled to
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - business_id
      - created_at
      - currency
      - document
      - id
      - receipt_date
      - reconciled_bank_transactions
      - total_amount
      - type
      - updated_at
      - vendor
    ReceiptCreateAPIRequest:
      type: object
      description: |-
        Receipt creation serializer. Creates a Receipt with vendor.
        Supports document upload via 'document' field.
      properties:
        external_id:
          type: string
        vendor_id:
          type: string
          format: uuid
          nullable: true
        receipt_date:
          type: string
          format: date
        total_amount_cents:
          type: integer
          minimum: 1
          description: Total amount in cents
        receipt_number:
          type: string
        description:
          type: string
        payment_method:
          enum:
          - cash
          - credit_card
          - debit_card
          - bank_transfer
          - check
          - other
          - ''
          - null
          type: string
          description: |-
            * `cash` - Cash
            * `credit_card` - Credit Card
            * `debit_card` - Debit Card
            * `bank_transfer` - Bank Transfer
            * `check` - Check
            * `other` - Other
          x-spec-enum-id: bbdac02b15dc5948
          nullable: true
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          - ''
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
        metadata: {}
        document:
          allOf:
          - $ref: '#/components/schemas/ReceiptDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload (alternative to document_id)
      required:
      - receipt_date
      - total_amount_cents
    ReceiptDocumentUploadRequest:
      type: object
      description: Receipt specific document upload payload.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: receipt
        upload_source:
          type: string
        metadata: {}
        tags: {}
    ReceiptPaymentMethodStats:
      type: object
      description: Payment method breakdown for receipts.
      properties:
        cash:
          type: integer
          default: 0
          description: Number of cash receipts
        credit_card:
          type: integer
          default: 0
          description: Number of credit card receipts
        debit_card:
          type: integer
          default: 0
          description: Number of debit card receipts
        bank_transfer:
          type: integer
          default: 0
          description: Number of bank transfer receipts
        check:
          type: integer
          default: 0
          description: Number of check receipts
        other:
          type: integer
          default: 0
          description: Number of receipts with other payment methods
    ReceiptReconciliationLink:
      type: object
      description: Output serializer for receipt reconciliation link details
      properties:
        reconciliation_link_id:
          type: string
          format: uuid
          description: Unique identifier for the reconciliation link
        bank_transaction_id:
          type: string
          format: uuid
          description: Bank transaction UUID
        bank_transaction_date:
          type: string
          format: date
          description: Date of the bank transaction
        bank_transaction_amount:
          type: integer
          description: Bank transaction amount in cents
        reconciled_amount:
          type: integer
          description: Amount reconciled in cents
        currency:
          type: string
          description: Currency code (e.g., EUR, USD)
          maxLength: 3
        notes:
          type: string
          nullable: true
          description: Reconciliation notes
        evidence:
          description: Additional evidence data
        created_at:
          type: string
          format: date-time
          description: When the reconciliation was created
      required:
      - bank_transaction_amount
      - bank_transaction_date
      - bank_transaction_id
      - created_at
      - currency
      - evidence
      - notes
      - reconciled_amount
      - reconciliation_link_id
    ReceiptReconciliationList:
      type: object
      description: Response serializer for list of receipt reconciliations
      properties:
        reconciliations:
          type: array
          items:
            $ref: '#/components/schemas/ReceiptReconciliationLink'
          description: List of reconciliation links
      required:
      - reconciliations
    ReceiptReconciliationRequestRequest:
      type: object
      description: Request serializer for receipt reconciliation
      properties:
        notes:
          type: string
          description: Optional notes for the reconciliation
          maxLength: 500
        evidence:
          type: object
          additionalProperties: {}
          description: Supporting evidence for the reconciliation
        created_by:
          enum:
          - api
          - manual
          - auto
          - import
          type: string
          x-spec-enum-id: 5993daf453316fc6
          default: api
          description: |-
            Source of reconciliation (api, manual, auto, import)

            * `api` - api
            * `manual` - manual
            * `auto` - auto
            * `import` - import
        bank_transaction_id:
          type: string
          format: uuid
          description: Bank transaction ID to reconcile with
        amount_cents:
          type: integer
          nullable: true
          description: Amount to reconcile in cents. If not provided, defaults to
            receipt total amount.
      required:
      - bank_transaction_id
    ReceiptStats:
      type: object
      description: Statistics for receipts with payment method breakdown.
      properties:
        all:
          type: integer
          description: Total number of receipts
        payment_method:
          allOf:
          - $ref: '#/components/schemas/ReceiptPaymentMethodStats'
          description: Breakdown by payment method
      required:
      - all
      - payment_method
    ReceiptUpdateAPIRequest:
      type: object
      description: |-
        Receipt update serializer. Applies partial updates to a Receipt.
        Supports document upload via 'document' field.
      properties:
        vendor_id:
          type: string
          format: uuid
          nullable: true
        external_id:
          type: string
        receipt_number:
          type: string
        description:
          type: string
        payment_method:
          enum:
          - cash
          - credit_card
          - debit_card
          - bank_transfer
          - check
          - other
          - ''
          - null
          type: string
          description: |-
            * `cash` - Cash
            * `credit_card` - Credit Card
            * `debit_card` - Debit Card
            * `bank_transfer` - Bank Transfer
            * `check` - Check
            * `other` - Other
          x-spec-enum-id: bbdac02b15dc5948
          nullable: true
        metadata: {}
        receipt_date:
          type: string
          format: date
        total_amount_cents:
          type: integer
          minimum: 1
          description: Total amount in cents
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          - ''
          type: string
          description: |-
            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
          x-spec-enum-id: 7e6a70e4775b3009
        document:
          allOf:
          - $ref: '#/components/schemas/ReceiptDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    ReconciliationResponse:
      type: object
      description: Unified response for all reconciliation operations
      properties:
        entity_type:
          type: string
          description: Type of entity reconciled (invoice, bill, receipt, etc.)
        entity_id:
          type: string
          format: uuid
          description: ID of the reconciled entity
        bank_transaction_id:
          type: string
          format: uuid
          description: Bank transaction ID
        reconciliation_link_id:
          type: string
          format: uuid
          description: Reconciliation link ID
        payment_id:
          type: string
          format: uuid
          description: Payment ID (when applicable)
        payment_created:
          type: boolean
          description: Whether a new payment was created during reconciliation
        payment_amount_cents:
          type: integer
          description: Payment amount in cents
        entity_previous_balance_cents:
          type: integer
          description: Entity balance before reconciliation (cents) - only for Invoice/Bill
        entity_new_balance_cents:
          type: integer
          description: Entity balance after reconciliation (cents) - only for Invoice/Bill
        entity_fully_settled:
          type: boolean
          description: Whether the entity is fully paid/settled
        bank_transaction_fully_reconciled:
          type: boolean
          description: Whether the bank transaction is fully reconciled
        bank_transaction_remaining_cents:
          type: integer
          description: Remaining unreconciled amount on bank transaction (cents)
        currency:
          type: string
          description: Currency code (e.g., GBP, EUR, USD)
        created_at:
          type: string
          format: date-time
          description: Timestamp of reconciliation
        metadata:
          type: object
          additionalProperties: {}
          description: Additional metadata
      required:
      - bank_transaction_fully_reconciled
      - bank_transaction_id
      - bank_transaction_remaining_cents
      - created_at
      - currency
      - entity_id
      - entity_type
      - reconciliation_link_id
    RecordWriteOffRequestRequest:
      type: object
      description: Request body for recording a write-off.
      properties:
        external_id:
          type: string
          description: Your unique identifier for this write-off (used for idempotency)
        amount_cents:
          type: integer
          minimum: 1
          description: Amount to write off in cents
        memo:
          type: string
          description: Reason or description for writing off this invoice amount
        destination_account:
          allOf:
          - $ref: '#/components/schemas/DestinationLedgerAccountInputRequest'
          description: Bad debt expense account identifier (AccountId format)
        write_off_at:
          type: string
          format: date-time
          description: Date/time of write-off (ISO 8601 format, defaults to now)
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Transaction tags for categorization and tracking
    Refund:
      type: object
      description: Serializer for refunds (simple response). All amounts in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique refund identifier
        external_id:
          type: string
          description: Your unique identifier for this refund (used for idempotency)
          maxLength: 255
        refunded_amount:
          type: integer
          description: Total refunded amount in cents
          readOnly: true
        status:
          enum:
          - pending
          - processing
          - paid
          - failed
          - cancelled
          type: string
          x-spec-enum-id: c671b6dd1cffeef4
          description: |-
            Refund status (pending, processing, paid, failed, cancelled)

            * `pending` - Pending
            * `processing` - Processing
            * `paid` - Paid
            * `failed` - Failed
            * `cancelled` - Cancelled
        completed_at:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when refund was fully paid
        is_dedicated:
          type: boolean
          description: Whether this is a dedicated refund (true/false)
        memo:
          type: string
          description: Description or reason for the refund
        reference_number:
          type: string
          description: Reference number for tracking
          maxLength: 100
        metadata:
          description: Custom key-value pairs for additional context
        customer_id:
          type: string
          format: uuid
          readOnly: true
          description: UUID of the customer receiving the refund
        customer_name:
          type: string
          readOnly: true
          description: Customer display name
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/RefundAllocation'
          readOnly: true
        refund_payments:
          type: array
          items:
            $ref: '#/components/schemas/RefundPayment'
          readOnly: true
        document:
          allOf:
          - $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: Latest document linked to this refund
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          x-spec-enum-id: 7e6a70e4775b3009
          description: |-
            Three-letter ISO 4217 currency code (EUR, GBP, USD)

            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Refund creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
      required:
      - allocations
      - created_at
      - customer_id
      - customer_name
      - document
      - id
      - refund_payments
      - refunded_amount
      - updated_at
    RefundAllocation:
      type: object
      description: Serializer for refund allocations. All amounts in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique allocation identifier
        allocation_type:
          enum:
          - invoice
          - payment
          - credit
          - line_item
          type: string
          x-spec-enum-id: 43480172e47a143a
          description: |-
            Type of allocation (invoice, line_item, etc.)

            * `invoice` - Invoice Refund
            * `payment` - Payment Refund
            * `credit` - Customer Credit
            * `line_item` - Line Item Refund
        amount:
          type: integer
          description: Allocation amount in cents
          readOnly: true
        invoice_id:
          type: string
          format: uuid
          description: Invoice ID if allocated to invoice
          readOnly: true
        invoice_number:
          type: string
          description: Invoice number if allocated to invoice
          readOnly: true
        invoice_outstanding_balance_cents:
          type: integer
          description: Invoice outstanding balance in cents if allocated to invoice
          readOnly: true
        target_description:
          type: string
          readOnly: true
        description:
          type: string
          description: Allocation description or notes
          maxLength: 500
        allocation_date:
          type: string
          format: date-time
          description: Date when allocation was made
      required:
      - allocation_type
      - amount
      - id
      - invoice_id
      - invoice_number
      - invoice_outstanding_balance_cents
      - target_description
    RefundAllocationSummary:
      type: object
      description: Refund allocation summary for invoice detail view - shows refunds
        allocated to this invoice.
      properties:
        refund_id:
          type: string
          format: uuid
        reference_number:
          type: string
        amount_cents:
          type: integer
        allocated_at:
          type: string
          format: date-time
      required:
      - allocated_at
      - amount_cents
      - refund_id
    RefundDocumentUploadRequest:
      type: object
      description: Refund specific document upload payload.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: refund
        upload_source:
          type: string
        metadata: {}
        tags: {}
    RefundPayment:
      type: object
      description: Serializer for refund payments. All amounts in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique refund payment identifier
        refund_id:
          type: string
          format: uuid
          readOnly: true
          description: ID of the refund this payment belongs to
        external_id:
          type: string
          description: Your unique identifier for idempotency (unique within refund)
          maxLength: 255
        refunded_amount:
          type: integer
          description: Refunded amount in cents
          readOnly: true
        refund_processing_fee:
          type: integer
          description: Processing fee in cents
          readOnly: true
        completed_at:
          type: string
          format: date-time
          nullable: true
          description: Date and time when refund payment was completed
        method:
          enum:
          - BANK_TRANSFER
          - CREDIT_CARD
          - DEBIT_CARD
          - ACH
          - CHECK
          - CASH
          - PAYPAL
          - STRIPE
          - OTHER
          type: string
          x-spec-enum-id: ba977578c39a8b5e
          description: |-
            Payment method used for refund (CASH, CHECK, CREDIT_CARD, BANK_TRANSFER, etc.)

            * `BANK_TRANSFER` - Bank Transfer
            * `CREDIT_CARD` - Credit Card
            * `DEBIT_CARD` - Debit Card
            * `ACH` - ACH/Direct Debit
            * `CHECK` - Check/Cheque
            * `CASH` - Cash
            * `PAYPAL` - PayPal
            * `STRIPE` - Stripe
            * `OTHER` - Other
        processor:
          type: string
          description: Payment processor used (e.g., Stripe, PayPal, manual)
          maxLength: 100
        transaction_tags:
          description: List of tags for categorization and reconciliation tracking
        memo:
          type: string
          description: Optional description or notes for this refund payment
        metadata:
          description: Custom key-value pairs for payment context
        reconciled_bank_transactions:
          type: array
          items:
            $ref: '#/components/schemas/EntityReconciliationDetail'
          readOnly: true
          description: Bank transactions this refund payment is reconciled to
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when refund payment record was created
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Timestamp when refund payment record was last updated
      required:
      - created_at
      - id
      - reconciled_bank_transactions
      - refund_id
      - refund_processing_fee
      - refunded_amount
      - updated_at
    RefundReconciliationRequestRequest:
      type: object
      description: Request serializer for refund payment reconciliation
      properties:
        notes:
          type: string
          description: Optional notes for the reconciliation
          maxLength: 500
        evidence:
          type: object
          additionalProperties: {}
          description: Supporting evidence for the reconciliation
        created_by:
          enum:
          - api
          - manual
          - auto
          - import
          type: string
          x-spec-enum-id: 5993daf453316fc6
          default: api
          description: |-
            Source of reconciliation (api, manual, auto, import)

            * `api` - api
            * `manual` - manual
            * `auto` - auto
            * `import` - import
        refund_id:
          type: string
          format: uuid
          description: Refund ID to reconcile
        payment_method:
          enum:
          - bank_transfer
          - credit_card
          - debit_card
          - ach
          - check
          - cash
          - wire
          - paypal
          - stripe
          - other
          type: string
          x-spec-enum-id: 6a4918e6dc1589b2
          default: bank_transfer
          description: |-
            Payment method for the reconciliation

            * `bank_transfer` - bank_transfer
            * `credit_card` - credit_card
            * `debit_card` - debit_card
            * `ach` - ach
            * `check` - check
            * `cash` - cash
            * `wire` - wire
            * `paypal` - paypal
            * `stripe` - stripe
            * `other` - other
        amount_cents:
          type: integer
          minimum: 1
          nullable: true
          description: Amount to reconcile in cents. If not provided, uses min(refund_amount,
            bank_remaining).
      required:
      - refund_id
    RefundStats:
      type: object
      description: Statistics for customer refunds.
      properties:
        all:
          type: integer
          description: Total number of refunds
        processed:
          type: integer
          description: Number of processed (paid) refunds
      required:
      - all
      - processed
    RefundUnreconciliationRequestRequest:
      type: object
      description: Request serializer for refund payment unreconciliation
      properties:
        refund_id:
          type: string
          format: uuid
          description: Refund ID to unreconcile
      required:
      - refund_id
    RefundUpdateRequest:
      type: object
      description: Serializer for updating refunds with optional document upload.
      properties:
        memo:
          type: string
          description: Description or reason for the refund
        reference_number:
          type: string
          description: Reference number for tracking
          maxLength: 100
        metadata:
          nullable: true
          description: Custom key-value pairs
        document:
          allOf:
          - $ref: '#/components/schemas/RefundDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    SearchAccountsRequest:
      type: object
      description: Validate search_accounts endpoint input.
      properties:
        parameters:
          type: object
          additionalProperties: {}
      required:
      - parameters
    SignupRequest:
      type: object
      description: Serializer for user signup.
      properties:
        email:
          type: string
          format: email
          minLength: 1
        password:
          type: string
          writeOnly: true
          minLength: 8
        first_name:
          type: string
          minLength: 1
          maxLength: 150
        last_name:
          type: string
          minLength: 1
          maxLength: 150
      required:
      - email
      - first_name
      - last_name
      - password
    SourceInfo:
      type: object
      description: |-
        Serializer for source information in journal entry detail.

        Contains information about the source documents (invoices, bills, etc.)
        and bank transactions that generated this journal entry.
      properties:
        bank_transaction:
          allOf:
          - $ref: '#/components/schemas/BankTransactionInfo'
          nullable: true
          description: Bank transaction details if this entry is linked to a bank
            transaction
        linked_documents:
          type: array
          items:
            $ref: '#/components/schemas/LinkedDocument'
          description: List of source documents (invoices, bills, credit notes, etc.)
            linked to this entry
    SplitTransactionItemRequest:
      type: object
      description: |-
        Serializer for individual split transaction item
        All amounts in cents (integers)
      properties:
        amount_cents:
          type: integer
          minimum: 1
          description: Amount for this split in cents (must be positive)
        subcategory_id:
          type: string
          format: uuid
          description: UUID of the subcategory for this split
        description:
          type: string
          description: Optional description for this split
          maxLength: 255
      required:
      - amount_cents
      - subcategory_id
    SplitTransactionRequestRequest:
      type: object
      description: Serializer for transaction split request
      properties:
        transactions:
          type: array
          items:
            $ref: '#/components/schemas/SplitTransactionItemRequest'
          description: List of transaction splits (minimum 2 required)
      required:
      - transactions
    SplitTransactionResponse:
      type: object
      description: Serializer for transaction split response
      properties:
        success:
          type: boolean
        message:
          type: string
        data: {}
      required:
      - data
      - message
      - success
    SubcategoryWithCategory:
      type: object
      description: |-
        Serializer for subcategory with parent category details.

        Used in transaction responses to show both category and subcategory.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        code:
          type: string
          description: Code for the subcategory (e.g., 'local_transport', 'saas_subscriptions')
          maxLength: 100
        name:
          type: string
          description: Display name for the subcategory (e.g., 'Local Transport',
            'SaaS Subscriptions')
          maxLength: 200
        description:
          type: string
          description: Detailed description of what types of transactions belong to
            this subcategory
        full_code:
          type: string
          readOnly: true
        category:
          allOf:
          - $ref: '#/components/schemas/TransactionCategory'
          readOnly: true
        is_active:
          type: boolean
          description: Whether this subcategory is active and available for selection
      required:
      - category
      - code
      - full_code
      - id
      - name
    SubtypeGroup:
      type: object
      description: |-
        Grouped accounts by AccountSubtype.

        - display_name: From AccountSubtype.label
        - total_cents: Sum of all line items
        - line_items: Individual accounts with this subtype
      properties:
        display_name:
          type: string
          description: Display name from AccountSubtype.label
        total_cents:
          type: integer
          description: Subtotal in cents
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/LineItem'
          description: Individual accounts
      required:
      - display_name
      - total_cents
    SystemHealth:
      type: object
      description: Serializer for system health check
      properties:
        status:
          type: string
          readOnly: true
        total_partners:
          type: integer
          readOnly: true
        total_businesses:
          type: integer
          readOnly: true
        total_users:
          type: integer
          readOnly: true
        database_status:
          type: string
          readOnly: true
      required:
      - database_status
      - status
      - total_businesses
      - total_partners
      - total_users
    Task:
      type: object
      description: |-
        Serializer for Task model with related entity details.

        Provides task information for business owners including:
        - Task metadata (title, description, status)
        - Submission state (has_submission, current_submission)
        - Rejection information when applicable
        - Linked entity details (transaction, invoice, bill)
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          description: 'Short title describing the task. Example: ''Missing receipt
            for Office Depot'''
        description:
          type: string
          description: 'Detailed description or question from the bookkeeper. Example:
            ''Please provide the receipt for €250 charge on Jan 6, 2025.'''
        status:
          enum:
          - pending_response
          - in_review
          - closed
          type: string
          x-spec-enum-id: ea18c01c61dd6cc1
          description: |-
            Current task status: pending_response (waiting for owner), in_review (bookkeeper reviewing), closed (completed)

            * `pending_response` - Pending Response
            * `in_review` - In Review
            * `closed` - Closed
        rejection_reason:
          type: string
          readOnly: true
          description: 'Reason provided when bookkeeper rejected the last submission.
            Empty if not rejected. Example: ''Document is blurry, please upload clearer
            image.'''
        accounting_period:
          type: string
          format: uuid
          nullable: true
          description: Associated accounting period for monthly grouping
        accounting_period_name:
          type: string
          description: 'Name of the accounting period. Example: ''2025-01'''
          readOnly: true
        created_by:
          type: string
          format: uuid
          nullable: true
        created_by_name:
          type: string
          description: Display name of the bookkeeper who created this task
          readOnly: true
        closed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        closed_by:
          type: string
          format: uuid
          nullable: true
        closed_by_name:
          type: string
          description: Display name of the bookkeeper who closed this task
          readOnly: true
        due_date:
          type: string
          format: date
          nullable: true
          description: 'Optional due date for task completion. Format: YYYY-MM-DD.
            Example: ''2025-01-15'''
        message_count:
          type: integer
          description: Total number of messages in this task thread
          readOnly: true
        question_count:
          type: integer
          description: Number of questions from bookkeeper
          readOnly: true
        answer_count:
          type: integer
          description: Number of answers from business owner
          readOnly: true
        document_count:
          type: integer
          description: Total documents attached across all messages
          readOnly: true
        is_overdue:
          type: boolean
          description: True if task has passed its due_date and is not closed
          readOnly: true
        has_unanswered_questions:
          type: boolean
          description: True if there are more questions than answers
          readOnly: true
        has_submission:
          type: boolean
          description: True if there is a current (non-rejected) submission from the
            owner
          readOnly: true
        current_submission:
          type: object
          additionalProperties: {}
          description: Summary of the current active submission, or null if none exists
          readOnly: true
        related_entity_type:
          type: string
          description: 'Type of linked entity: ''banktransaction'', ''invoice'', ''bill'',
            or null'
          readOnly: true
        related_entity_details:
          type: object
          additionalProperties: {}
          description: Summary details of the linked entity (amount, date, counterparty,
            etc.)
          readOnly: true
        metadata: {}
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - accounting_period_name
      - answer_count
      - closed_at
      - closed_by_name
      - created_at
      - created_by_name
      - current_submission
      - description
      - document_count
      - has_submission
      - has_unanswered_questions
      - id
      - is_overdue
      - message_count
      - question_count
      - rejection_reason
      - related_entity_details
      - related_entity_type
      - status
      - title
      - updated_at
    TaskCreate:
      type: object
      description: Serializer for creating tasks with atomic first question.
      properties:
        title:
          type: string
          maxLength: 255
        description:
          type: string
        accounting_period:
          type: string
          format: uuid
          nullable: true
          description: Associated accounting period for monthly grouping
        due_date:
          type: string
          format: date
          nullable: true
          description: Optional due date for task completion
        metadata: {}
      required:
      - title
    TaskCreateRequest:
      type: object
      description: Serializer for creating tasks with atomic first question.
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 255
        description:
          type: string
        accounting_period:
          type: string
          format: uuid
          nullable: true
          description: Associated accounting period for monthly grouping
        due_date:
          type: string
          format: date
          nullable: true
          description: Optional due date for task completion
        related_entity_type:
          type: string
          writeOnly: true
          minLength: 1
          description: Model name of related entity (e.g., 'banktransaction', 'invoice',
            'bill')
        related_entity_id:
          type: string
          format: uuid
          writeOnly: true
          description: ID of related entity
        first_question:
          type: string
          writeOnly: true
          minLength: 1
          description: Initial question from accountant (creates first TaskMessage)
        metadata: {}
      required:
      - first_question
      - title
    TaskDetail:
      type: object
      description: Serializer for task detail response.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          readOnly: true
        description:
          type: string
          readOnly: true
        status:
          enum:
          - pending_response
          - in_review
          - closed
          type: string
          description: |-
            * `pending_response` - Pending Response
            * `in_review` - In Review
            * `closed` - Closed
          x-spec-enum-id: ea18c01c61dd6cc1
          readOnly: true
        rejection_reason:
          type: string
          readOnly: true
          description: Reason provided when bookkeeper rejects a submission
        due_date:
          type: string
          format: date
          readOnly: true
          nullable: true
          description: Optional due date for task completion
        is_overdue:
          type: boolean
          readOnly: true
        message_count:
          type: integer
          readOnly: true
        created_by_name:
          type: string
          nullable: true
          description: Get name of the user who created the task.
          readOnly: true
        closed_by_name:
          type: string
          nullable: true
          description: Get name of the user who closed the task.
          readOnly: true
        closed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - closed_at
      - closed_by_name
      - created_at
      - created_by_name
      - description
      - due_date
      - id
      - is_overdue
      - message_count
      - rejection_reason
      - status
      - title
      - updated_at
    TaskList:
      type: object
      description: Serializer for task list response.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          readOnly: true
        description:
          type: string
          readOnly: true
        status:
          enum:
          - pending_response
          - in_review
          - closed
          type: string
          description: |-
            * `pending_response` - Pending Response
            * `in_review` - In Review
            * `closed` - Closed
          x-spec-enum-id: ea18c01c61dd6cc1
          readOnly: true
        due_date:
          type: string
          format: date
          readOnly: true
          nullable: true
          description: Optional due date for task completion
        is_overdue:
          type: boolean
          readOnly: true
        created_by_name:
          type: string
          nullable: true
          description: Get name of the user who created the task.
          readOnly: true
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - created_at
      - created_by_name
      - description
      - due_date
      - id
      - is_overdue
      - status
      - title
      - updated_at
    TaskMessage:
      type: object
      description: |-
        Serializer for TaskMessage (read-only, for GET responses).

        Represents a submission/response from the business owner to a task,
        including any attached documents with presigned download URLs.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        task:
          type: string
          format: uuid
          readOnly: true
        message_type:
          enum:
          - question
          - answer
          type: string
          description: |-
            * `question` - Question
            * `answer` - Answer
          x-spec-enum-id: 354b60dcababf8a6
        message:
          type: string
          description: 'The response text from the business owner. Example: ''This
            was for office supplies - printer paper and ink.'''
        author_type:
          type: string
          description: 'Type of author entity: ''user'' or ''business'''
          readOnly: true
        author_name:
          type: string
          description: 'Display name of the author. Example: ''John Owner'''
          readOnly: true
        document_count:
          type: integer
          description: Number of documents attached to this message
          readOnly: true
        documents:
          type: array
          items:
            $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: List of attached documents with presigned download URLs (only
            in detail view)
        rejected_at:
          type: string
          format: date-time
          readOnly: true
          description: 'Timestamp when this submission was rejected, or null if not
            rejected. Example: ''2025-01-08T14:30:00Z'''
        rejection_reason:
          type: string
          readOnly: true
          description: 'Reason provided when this submission was rejected. Example:
            ''Document is blurry, please upload clearer image.'''
        metadata: {}
        submitted_at:
          type: string
          format: date-time
          readOnly: true
          description: 'When this submission was created. Example: ''2025-01-08T14:00:00Z'''
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
      required:
      - author_name
      - author_type
      - created_at
      - document_count
      - documents
      - id
      - message
      - message_type
      - rejected_at
      - rejection_reason
      - submitted_at
      - task
      - updated_at
    TaskMessageCreate:
      type: object
      description: Serializer for creating TaskMessage with multiple document upload
        support.
      properties:
        message_type:
          enum:
          - question
          - answer
          type: string
          description: |-
            * `question` - Question
            * `answer` - Answer
          x-spec-enum-id: 354b60dcababf8a6
        message:
          type: string
        metadata: {}
      required:
      - message
      - message_type
    TaskMessageCreateRequest:
      type: object
      description: Serializer for creating TaskMessage with multiple document upload
        support.
      properties:
        message_type:
          enum:
          - question
          - answer
          type: string
          description: |-
            * `question` - Question
            * `answer` - Answer
          x-spec-enum-id: 354b60dcababf8a6
        message:
          type: string
          minLength: 1
        metadata: {}
        documents:
          type: array
          items:
            $ref: '#/components/schemas/TaskMessageDocumentUploadRequest'
          writeOnly: true
          description: Optional list of document uploads (max 10 files per request).
          maxItems: 10
      required:
      - message
      - message_type
    TaskMessageDocumentUpload:
      type: object
      description: TaskMessage specific document upload payload.
      properties:
        document_type:
          type: string
          default: task_attachment
        upload_source:
          type: string
        metadata: {}
        tags: {}
    TaskMessageDocumentUploadRequest:
      type: object
      description: TaskMessage specific document upload payload.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: task_attachment
        upload_source:
          type: string
        metadata: {}
        tags: {}
    TaskMessageResponse:
      type: object
      description: Response serializer for task message creation.
      properties:
        id:
          type: string
          format: uuid
          description: Message ID
        message_type:
          type: string
          description: Message type
        message:
          type: string
          description: Message content
        created_at:
          type: string
          format: date-time
          description: Creation timestamp
      required:
      - created_at
      - id
      - message
      - message_type
    TaskMessageUpdate:
      type: object
      description: Serializer for updating TaskMessage with multiple document upload
        support.
      properties:
        message:
          type: string
        metadata: {}
    TaskRequest:
      type: object
      description: |-
        Serializer for Task model with related entity details.

        Provides task information for business owners including:
        - Task metadata (title, description, status)
        - Submission state (has_submission, current_submission)
        - Rejection information when applicable
        - Linked entity details (transaction, invoice, bill)
      properties:
        title:
          type: string
          minLength: 1
          description: 'Short title describing the task. Example: ''Missing receipt
            for Office Depot'''
        description:
          type: string
          minLength: 1
          description: 'Detailed description or question from the bookkeeper. Example:
            ''Please provide the receipt for €250 charge on Jan 6, 2025.'''
        status:
          enum:
          - pending_response
          - in_review
          - closed
          type: string
          x-spec-enum-id: ea18c01c61dd6cc1
          description: |-
            Current task status: pending_response (waiting for owner), in_review (bookkeeper reviewing), closed (completed)

            * `pending_response` - Pending Response
            * `in_review` - In Review
            * `closed` - Closed
        accounting_period:
          type: string
          format: uuid
          nullable: true
          description: Associated accounting period for monthly grouping
        created_by:
          type: string
          format: uuid
          nullable: true
        closed_by:
          type: string
          format: uuid
          nullable: true
        due_date:
          type: string
          format: date
          nullable: true
          description: 'Optional due date for task completion. Format: YYYY-MM-DD.
            Example: ''2025-01-15'''
        metadata: {}
      required:
      - description
      - status
      - title
    TaxLineItemRequest:
      type: object
      description: Serializer for tax line items on invoice line items
      properties:
        tax_account:
          nullable: true
          description: Tax account object (optional)
        amount:
          type: integer
          description: Tax amount in cents
        discount_amount:
          type: integer
          default: 0
          description: Discount on tax in cents
      required:
      - amount
    TokenExchangeRequest:
      type: object
      description: Serializer for public token exchange request.
      properties:
        public_token:
          type: string
          minLength: 1
          description: Public token received from Plaid Link
          maxLength: 500
      required:
      - public_token
    TokenExchangeResponse:
      type: object
      description: Serializer for token exchange response.
      properties:
        success:
          type: boolean
        message:
          type: string
        bank_link_id:
          type: string
          format: uuid
      required:
      - message
      - success
    TransactionCategorizationResponse:
      type: object
      description: |-
        Serializer for transaction categorization responses.
        Provides comprehensive categorization details and status.

        Two-Status Model:
        - categorization_status: Whether category is set (pending, categorized, manual_review, approved)
        - approval_status: Whether approved for posting (pending_approval, ai_approved, approved)

        JE triggers when: categorization_status=categorized AND approval_status IN (ai_approved, approved)
      properties:
        transaction_id:
          type: string
          format: uuid
          description: Transaction UUID
        categorization_status:
          type: string
          description: 'Categorization status: pending, categorized, manual_review,
            approved'
        approval_status:
          type: string
          description: 'Approval status: pending_approval (needs review), ai_approved
            (auto-approved by AI), approved (human approved)'
        category:
          type: object
          additionalProperties: {}
          nullable: true
          description: Category object with id, code, name
        subcategory:
          type: object
          additionalProperties: {}
          nullable: true
          description: Subcategory object with id, code, name, full_code
        requires_approval:
          type: boolean
          description: True if approval_status=pending_approval, False if already
            approved
        categorized_by:
          type: string
          description: User/partner who performed categorization
        categorized_at:
          type: string
          format: date-time
          description: Timestamp when categorized
        updated_at:
          type: string
          format: date-time
          description: Timestamp when last updated
      required:
      - approval_status
      - categorization_status
      - categorized_at
      - categorized_by
      - category
      - requires_approval
      - subcategory
      - transaction_id
      - updated_at
    TransactionCategory:
      type: object
      description: |-
        Serializer for transaction category without nested subcategories.

        Used when only category information is needed.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        code:
          type: string
          description: Unique code for the category (e.g., 'travel_and_transport',
            'software_and_it')
          maxLength: 100
        name:
          type: string
          description: Display name for the category (e.g., 'Travel & Transport',
            'Software & IT')
          maxLength: 200
        description:
          type: string
          description: Detailed description of what types of transactions belong to
            this category
        is_active:
          type: boolean
          description: Whether this category is active and available for selection
      required:
      - code
      - id
      - name
    TransactionCategoryWithSubcategories:
      type: object
      description: |-
        Serializer for transaction category with nested subcategories.

        Returns the complete hierarchy for category selection in the UI.
        Only includes active subcategories.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        code:
          type: string
          description: Unique code for the category (e.g., 'travel_and_transport',
            'software_and_it')
          maxLength: 100
        name:
          type: string
          description: Display name for the category (e.g., 'Travel & Transport',
            'Software & IT')
          maxLength: 200
        description:
          type: string
          description: Detailed description of what types of transactions belong to
            this category
        subcategories:
          type: array
          items:
            $ref: '#/components/schemas/TransactionSubcategory'
          readOnly: true
          description: List of active subcategories
        subcategory_count:
          type: integer
          readOnly: true
          description: Number of active subcategories
        is_active:
          type: boolean
          description: Whether this category is active and available for selection
      required:
      - code
      - id
      - name
      - subcategories
      - subcategory_count
    TransactionSubcategory:
      type: object
      description: |-
        Serializer for transaction subcategory.

        Returns subcategory details including the full code for backward compatibility.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        code:
          type: string
          description: Code for the subcategory (e.g., 'local_transport', 'saas_subscriptions')
          maxLength: 100
        name:
          type: string
          description: Display name for the subcategory (e.g., 'Local Transport',
            'SaaS Subscriptions')
          maxLength: 200
        description:
          type: string
          description: Detailed description of what types of transactions belong to
            this subcategory
        full_code:
          type: string
          readOnly: true
          description: 'Full code in format: category.subcategory'
        is_active:
          type: boolean
          description: Whether this subcategory is active and available for selection
      required:
      - code
      - full_code
      - id
      - name
    UnCategorizeTransactionResponse:
      type: object
      description: |-
        Serializer for uncategorization response.

        Resets transaction to:
        - categorization_status: pending
        - approval_status: pending_approval

        Future implementation will include reversal journal entry details.
      properties:
        transaction_id:
          type: string
          format: uuid
          description: Transaction UUID
        categorization_status:
          type: string
          description: New categorization status (reset to 'pending')
        approval_status:
          type: string
          description: New approval status (reset to 'pending_approval')
        reversal_journal_entry_id:
          type: string
          format: uuid
          nullable: true
          description: Reversal journal entry ID (when ledger is implemented)
        uncategorized_at:
          type: string
          format: date-time
          description: Timestamp when uncategorized
        uncategorized_by:
          type: string
          description: User who performed uncategorization
      required:
      - approval_status
      - categorization_status
      - transaction_id
      - uncategorized_at
      - uncategorized_by
    UnCategorizeTransactionResponseRequest:
      type: object
      description: |-
        Serializer for uncategorization response.

        Resets transaction to:
        - categorization_status: pending
        - approval_status: pending_approval

        Future implementation will include reversal journal entry details.
      properties:
        transaction_id:
          type: string
          format: uuid
          description: Transaction UUID
        categorization_status:
          type: string
          minLength: 1
          description: New categorization status (reset to 'pending')
        approval_status:
          type: string
          minLength: 1
          description: New approval status (reset to 'pending_approval')
        reversal_journal_entry_id:
          type: string
          format: uuid
          nullable: true
          description: Reversal journal entry ID (when ledger is implemented)
        uncategorized_at:
          type: string
          format: date-time
          description: Timestamp when uncategorized
        uncategorized_by:
          type: string
          minLength: 1
          description: User who performed uncategorization
      required:
      - approval_status
      - categorization_status
      - transaction_id
      - uncategorized_at
      - uncategorized_by
    UnifiedDocumentUploadRequestRequest:
      type: object
      description: Request serializer for unified document upload endpoint
      properties:
        file:
          type: string
          format: binary
          description: PDF or image file (AR or AP document, max 50MB)
      required:
      - file
    UnifiedDocumentUploadResponse:
      type: object
      description: Response serializer for unified document upload endpoint
      properties:
        document_id:
          type: string
          format: uuid
          description: Unique identifier for the uploaded document
        task_id:
          type: string
          description: Celery task ID for tracking processing
        status:
          type: string
          description: Current status (always 'processing' initially)
        message:
          type: string
          description: Instructions for checking result after AR/AP classification
      required:
      - document_id
      - message
      - status
      - task_id
    UnmatchCustomerCreditNoteRequestRequest:
      type: object
      description: Request serializer for unmatching customer credit note from bank
        transaction
      properties:
        customer_credit_note_id:
          type: string
          format: uuid
          description: UUID of the customer credit note to unmatch
      required:
      - customer_credit_note_id
    UnmatchCustomerCreditNoteResponse:
      type: object
      description: Response serializer for unmatch customer credit note operation
      properties:
        unmatched:
          type: boolean
          description: Whether unmatch was successful
        customer_credit_note_id:
          type: string
          format: uuid
          description: UUID of the unmatched credit note
        bank_transaction_id:
          type: string
          format: uuid
          description: UUID of the bank transaction
        reconciliation_link_id:
          type: string
          format: uuid
          description: UUID of the reversed ReconciliationLink
        reversed_amount_cents:
          type: integer
          description: Amount reversed in cents
      required:
      - bank_transaction_id
      - customer_credit_note_id
      - reconciliation_link_id
      - reversed_amount_cents
      - unmatched
    UnmatchPayoutRequestRequest:
      type: object
      description: Request serializer for unmatching payout from bank transaction
      properties:
        payout_id:
          type: string
          format: uuid
          description: UUID of the payout to unmatch
      required:
      - payout_id
    UnmatchPayoutResponse:
      type: object
      description: Response serializer for unmatch payout operation
      properties:
        unmatched:
          type: boolean
          description: Whether unmatch was successful
        payout_id:
          type: string
          format: uuid
          description: UUID of the unmatched payout
        reconciliation_link_id:
          type: string
          format: uuid
          description: UUID of the reversed ReconciliationLink
      required:
      - payout_id
      - reconciliation_link_id
      - unmatched
    UnmatchVendorCreditNoteRequestRequest:
      type: object
      description: Request serializer for unmatching vendor credit note from bank
        transaction
      properties:
        vendor_credit_note_id:
          type: string
          format: uuid
          description: UUID of the vendor credit note to unmatch
      required:
      - vendor_credit_note_id
    UnmatchVendorCreditNoteResponse:
      type: object
      description: Response serializer for unmatch vendor credit note operation
      properties:
        unmatched:
          type: boolean
          description: Whether unmatch was successful
        vendor_credit_note_id:
          type: string
          format: uuid
          description: UUID of the unmatched credit note
        bank_transaction_id:
          type: string
          format: uuid
          description: UUID of the bank transaction
        reconciliation_link_id:
          type: string
          format: uuid
          description: UUID of the reversed ReconciliationLink
        reversed_amount_cents:
          type: integer
          description: Amount reversed in cents
      required:
      - bank_transaction_id
      - reconciliation_link_id
      - reversed_amount_cents
      - unmatched
      - vendor_credit_note_id
    UnreconciliationResponse:
      type: object
      description: Unified response for all unreconciliation operations
      properties:
        entity_type:
          type: string
          description: Type of entity unreconciled (invoice, bill, receipt, etc.)
        entity_id:
          type: string
          format: uuid
          description: ID of the unreconciled entity
        bank_transaction_id:
          type: string
          format: uuid
          description: Bank transaction ID
        payment_id:
          type: string
          format: uuid
          description: Payment ID (when applicable)
        payment_deleted:
          type: boolean
          description: Whether the payment was deleted during unreconciliation
        amount_reversed:
          type: integer
          description: Amount reversed during unreconciliation in cents
        entity_new_balance_cents:
          type: integer
          description: Entity balance after unreconciliation (cents)
        entity_status:
          type: string
          description: Entity status after unreconciliation
        reconciliation_link_id:
          type: string
          format: uuid
          description: Reconciliation link ID that was reversed
      required:
      - amount_reversed
      - bank_transaction_id
      - entity_id
      - entity_type
    UpdateBusiness:
      type: object
      description: Serializer for updating existing businesses
      properties:
        legal_name:
          type: string
          description: Legal registered name of the business
          maxLength: 255
        entity_type:
          type: string
          description: Business entity type (e.g., 'limited', 'gmbh', 'bv')
        phone_number:
          type: string
          description: Business phone number
        tin:
          type: string
          description: Tax identification number (other than VAT)
        vat_number:
          type: string
          description: EU VAT registration number
          maxLength: 20
        company_number:
          type: string
          description: Company registration number (e.g., Companies House number for
            UK)
          maxLength: 20
        province:
          type: string
          description: Province or state within the country
          maxLength: 100
        eu_nace_industry_code:
          type: string
          description: European NACE industry classification code
          maxLength: 10
        email:
          type: string
          format: email
          description: Primary email address for the business
        accounting_method:
          enum:
          - cash
          - accrual
          type: string
          x-spec-enum-id: 6f6d0e718e73bb81
          description: |-
            Accounting method: 'cash' or 'accrual'

            * `cash` - Cash Basis
            * `accrual` - Accrual Basis
        fiscal_year_end:
          type: string
          format: date
          description: 'Fiscal year end date (format: YYYY-MM-DD)'
        metadata:
          description: Custom JSON metadata for partner-specific data
    UpdateCustomerCreditRequest:
      type: object
      description: |-
        Update serializer for customer credits.

        Allows updating basic fields and replacing line items/allocations
        under safe conditions.
      properties:
        external_id:
          type: string
          description: Updated external system identifier (must remain unique within
            business)
        sent_at:
          type: string
          format: date-time
          description: Updated sent date/time (ISO 8601 format)
        memo:
          type: string
          description: Updated memo or description for the credit
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Updated transaction tags for categorization
        metadata:
          type: object
          additionalProperties: {}
          description: Updated custom key-value pairs (max 10kb)
        source_invoice_id:
          type: string
          format: uuid
          nullable: true
          description: Invoice ID this credit was created from (cannot be changed
            once set)
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/CustomerCreditLineItemRequest'
          description: Updated line items (cannot change once credit is applied or
            partially applied)
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/CustomerCreditAllocationRequest'
          description: Updated invoice allocations for this credit
        document:
          allOf:
          - $ref: '#/components/schemas/CustomerCreditDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    UpdateCustomerRequest:
      type: object
      description: Serializer for updating existing customers
      properties:
        external_id:
          type: string
          description: Your unique identifier for this customer
        reference_number:
          type: string
          description: Customer reference number for invoices and statements
        individual_name:
          type: string
          description: Individual/contact person name
        company_name:
          type: string
          description: Registered company name
        email:
          type: string
          format: email
          description: Primary email address for the customer
        mobile_phone:
          type: string
          description: Mobile phone number
        office_phone:
          type: string
          description: Office/landline phone number
        address_line1:
          type: string
          description: Street address line 1
        address_line2:
          type: string
          description: Street address line 2 (building, suite, etc.)
        city:
          type: string
          description: City or town
        state_county:
          type: string
          description: State, county, or region
        postal_code:
          type: string
          description: Postal/ZIP code
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code
        vat_number:
          type: string
          description: 'VAT registration number (for UK: GB followed by 9 digits)'
        tax_exempt:
          type: boolean
          description: Whether customer is exempt from tax/VAT
        status:
          enum:
          - active
          - archived
          - suspended
          type: string
          description: |-
            * `active` - Active
            * `archived` - Archived
            * `suspended` - Suspended
          x-spec-enum-id: 8c91d15064e148c5
        transaction_tags:
          type: array
          items: {}
          description: Array of tags for categorization and filtering
        notes:
          type: string
          description: Internal notes about the customer
        metadata:
          description: Custom JSON metadata for partner-specific data
        payment_terms_days:
          type: integer
          description: Number of days for payment terms (e.g., 30 for Net 30)
        credit_limit_cents:
          type: integer
          minimum: 0
          description: Maximum credit limit in cents (e.g., 100000 for £1,000)
        document:
          allOf:
          - $ref: '#/components/schemas/CustomerDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    UpdateMenuConfigRequest:
      type: object
      description: |-
        Serializer for menu configuration update operations.
        Validates the structure before saving.
      properties:
        menu:
          type: object
          additionalProperties:
            type: boolean
          description: Menu items visibility configuration
        sub_menu_tabs:
          type: object
          additionalProperties:
            type: boolean
          description: Sub-menu tabs visibility configuration
      required:
      - menu
    UpdatePaymentRequest:
      type: object
      description: |-
        Serializer for updating existing payments.
        Matches the create endpoint structure (InvoiceRecordPaymentRequestSerializer)
        to provide consistency between create and update APIs.
      properties:
        customer_id:
          type: string
          format: uuid
          description: Customer UUID (cannot be changed after creation)
        total_amount_cents:
          type: integer
          minimum: 1
          description: Updated total payment amount in cents (must not be less than
            allocated amount)
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/PaymentAllocationUpdateRequest'
          description: Updated list of invoice allocations (replaces existing allocations)
        payment_date:
          type: string
          format: date
          description: 'Updated payment date (ISO date format: YYYY-MM-DD)'
        currency:
          type: string
          minLength: 1
          description: Payment currency (cannot be changed after creation)
          maxLength: 3
        payment_method:
          enum:
          - bank_transfer
          - credit_card
          - debit_card
          - ach
          - check
          - cash
          - paypal
          - stripe
          - other
          type: string
          x-spec-enum-id: 1a9252035ec0bc4a
          description: |-
            Updated payment method (bank_transfer, card, cash, cheque, direct_debit)

            * `bank_transfer` - bank_transfer
            * `credit_card` - credit_card
            * `debit_card` - debit_card
            * `ach` - ach
            * `check` - check
            * `cash` - cash
            * `paypal` - paypal
            * `stripe` - stripe
            * `other` - other
        payment_reference:
          type: string
          description: Updated internal payment reference
        external_id:
          type: string
          description: Updated external identifier (must remain unique)
        note:
          type: string
          description: Updated internal notes or description
        notes:
          type: string
          description: Legacy field for notes (use 'note' instead)
        metadata:
          type: object
          additionalProperties: {}
          description: Updated custom key-value pairs
        references:
          type: object
          additionalProperties:
            type: string
          description: Updated payment references (bank_reference, end_to_end_id,
            payment_reference)
        processor_reference:
          type: string
          description: Updated payment processor reference
          maxLength: 255
        bank_reference:
          type: string
          description: Updated bank transaction reference
          maxLength: 100
        status:
          enum:
          - pending
          - processing
          - completed
          - failed
          - cancelled
          - refunded
          type: string
          x-spec-enum-id: 760241f0a4b58134
          description: |-
            Updated payment status (pending, processing, completed, failed, cancelled, refunded)

            * `pending` - Pending
            * `processing` - Processing
            * `completed` - Completed
            * `failed` - Failed
            * `cancelled` - Cancelled
            * `refunded` - Refunded
        transaction_tags:
          type: array
          items:
            type: string
            minLength: 1
          description: Updated tags for categorization
        payment_processor:
          type: string
          description: Updated payment processor name
          maxLength: 100
        processing_fee_cents:
          type: integer
          minimum: 0
          description: Updated processing fee in cents
    UpdateVendorCreditRequest:
      type: object
      description: |-
        Update serializer for vendor credits.

        Allows updating basic fields and replacing line items/allocations
        under safe conditions.
      properties:
        external_id:
          type: string
          description: Updated external system identifier (must remain unique within
            business)
        received_at:
          type: string
          format: date-time
          description: Updated received date/time (ISO 8601 format, changes status
            from draft to received)
        memo:
          type: string
          description: Updated memo or description for the credit
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Updated transaction tags for categorization (array of key-value
            pairs)
        metadata:
          type: object
          additionalProperties: {}
          description: Updated custom key-value pairs (max 10kb)
        source_bill_id:
          type: string
          format: uuid
          nullable: true
          description: Bill ID this credit was created from (cannot be changed once
            set)
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/VendorCreditLineItemRequest'
          description: Updated line items (cannot change once credit is applied or
            partially applied)
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/VendorCreditAllocationRequest'
          description: Updated bill allocations for this credit
        document:
          allOf:
          - $ref: '#/components/schemas/VendorCreditDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    UpdateVendorRequest:
      type: object
      description: Input serializer for updating a vendor
      properties:
        external_id:
          type: string
          description: Updated external identifier (must remain unique)
        individual_name:
          type: string
          description: Updated vendor individual name
        company_name:
          type: string
          description: Updated registered company name
        email:
          type: string
          format: email
          description: Updated primary email address
        mobile_phone:
          type: string
          description: Updated mobile phone number (E.164 format)
        office_phone:
          type: string
          description: Updated office phone number (E.164 format)
        address_string:
          type: string
          description: Updated vendor mailing address
        memo:
          type: string
          description: Updated internal notes or description
        transaction_tags:
          type: array
          items: {}
          description: Updated tags for categorization
        vendor_number:
          type: string
          description: Updated vendor number (must be unique)
        document:
          allOf:
          - $ref: '#/components/schemas/VendorDocumentUploadRequest'
          writeOnly: true
          description: Optional document upload
    ValidateAccountsRequest:
      type: object
      description: Validate validate_accounts endpoint input.
      properties:
        parameters:
          type: object
          additionalProperties: {}
      required:
      - parameters
    ValidationErrorResponse:
      type: object
      description: Validation error response with field-specific errors
      properties:
        error_code:
          type: string
          description: Error code (e.g., 'validation_error')
        message:
          type: string
          nullable: true
          description: Human-readable error message
        detail:
          type: object
          additionalProperties: {}
          description: Contains field_errors and additional context
        request_id:
          type: string
          description: Request ID for tracing
      required:
      - detail
      - error_code
      - message
    Vendor:
      type: object
      description: Serializer for vendor objects returned by the vendors list endpoint
      properties:
        type:
          type: string
          readOnly: true
          description: Resource type (always 'VendorData')
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique vendor identifier
        external_id:
          type: string
          description: Your unique identifier for this vendor (used for idempotency)
          maxLength: 255
        individual_name:
          type: string
          description: Vendor individual name (for sole traders/freelancers)
          maxLength: 255
        company_name:
          type: string
          description: Registered company name (for limited companies)
          maxLength: 255
        email:
          type: string
          format: email
          description: Primary email address for vendor communications
          maxLength: 254
        mobile_phone:
          type: string
          readOnly: true
          description: Mobile phone number (E.164 format, e.g., +44 7700 900123)
        office_phone:
          type: string
          readOnly: true
          description: Office phone number (E.164 format, e.g., +44 20 7946 0958)
        address_string:
          type: string
          readOnly: true
          description: Full formatted address (read-only, auto-generated)
        memo:
          type: string
          readOnly: true
          description: Internal notes or description for this vendor
        status:
          type: string
          readOnly: true
          description: Vendor status (ACTIVE, INACTIVE, ARCHIVED, BLOCKED)
        transaction_tags:
          type: array
          items: {}
          readOnly: true
          description: List of tags for categorization
        documents:
          type: array
          items:
            $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: All documents linked to this vendor with presigned URLs
      required:
      - address_string
      - documents
      - id
      - memo
      - mobile_phone
      - office_phone
      - status
      - transaction_tags
      - type
    VendorAging:
      type: object
      description: |-
        AP aging for a single vendor.

        Includes:
        - Vendor identification
        - Total outstanding amount
        - Breakdown by aging bucket
      properties:
        vendor_id:
          type: string
          format: uuid
          description: Vendor UUID
        vendor_name:
          type: string
          description: Vendor name (company_name or individual_name)
        total_outstanding_cents:
          type: integer
          description: Total outstanding amount for this vendor in cents
        aging_buckets:
          allOf:
          - $ref: '#/components/schemas/APAgingBuckets'
          description: Outstanding amount by aging bucket
      required:
      - aging_buckets
      - total_outstanding_cents
      - vendor_id
      - vendor_name
    VendorCredit:
      type: object
      description: Vendor credit serializer for API responses.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique vendor credit identifier
        external_id:
          type: string
          description: Your external system identifier for this credit (used for idempotency)
          maxLength: 255
        status:
          type: string
          description: 'Credit status: draft, received, partially_applied, applied,
            void (computed from allocations)'
          readOnly: true
        received_at:
          type: string
          format: date-time
          readOnly: true
          description: When the credit was received
        vendor:
          allOf:
          - $ref: '#/components/schemas/VendorEmbedded'
          readOnly: true
          description: Vendor who issued the credit (inline details)
        source_bill_id:
          type: string
          format: uuid
          readOnly: true
          nullable: true
          description: Bill ID this credit was created from (origin tracking, not
            allocation)
        line_items:
          type: array
          items:
            $ref: '#/components/schemas/VendorCreditLineItemResponse'
          readOnly: true
          description: Array of credit line items
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/VendorCreditBillAllocationResponse'
          readOnly: true
          description: Array of bill allocations
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Transaction tags for the credit
          readOnly: true
        total_amount:
          type: integer
          description: Total credit amount in cents
          readOnly: true
        applied_amount:
          type: integer
          description: Applied credit amount in cents
          readOnly: true
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          x-spec-enum-id: 7e6a70e4775b3009
          description: |-
            Credit currency (e.g., GBP, EUR, USD)

            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
        document:
          allOf:
          - $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: Latest document linked to this vendor credit
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Credit creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
      required:
      - allocations
      - applied_amount
      - created_at
      - document
      - id
      - line_items
      - received_at
      - source_bill_id
      - status
      - tags
      - total_amount
      - updated_at
      - vendor
    VendorCreditAllocationRequest:
      type: object
      description: Serializer for vendor credit allocations to bills.
      properties:
        amount:
          type: integer
          minimum: 1
          description: Amount to allocate to bill in cents
        bill_id:
          type: string
          format: uuid
          description: Bill ID to allocate credit to
      required:
      - amount
      - bill_id
    VendorCreditAllocationSummary:
      type: object
      description: Credit allocation summary for bill detail view - shows vendor credits
        applied to this bill.
      properties:
        amount_cents:
          type: integer
        applied_at:
          type: string
          format: date-time
        vendor_credit_id:
          type: string
          format: uuid
        vendor_credit_number:
          type: string
      required:
      - amount_cents
      - applied_at
      - vendor_credit_id
    VendorCreditBillAllocationResponse:
      type: object
      description: Response serializer for vendor credit allocations to bills (for
        OpenAPI documentation).
      properties:
        bill_id:
          type: string
          format: uuid
          description: UUID of the bill this credit is allocated to
        bill_number:
          type: string
          description: Bill number (e.g., BILL-00019)
        amount_cents:
          type: integer
          description: Amount allocated to this bill in cents
        bill_outstanding_balance_cents:
          type: integer
          description: Current outstanding balance on the bill in cents (after all
            allocations)
        applied_at:
          type: string
          format: date-time
          description: When the allocation was applied
      required:
      - amount_cents
      - applied_at
      - bill_id
      - bill_number
      - bill_outstanding_balance_cents
    VendorCreditDocumentUploadRequest:
      type: object
      description: Vendor credit specific document upload payload.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: vendor_credit
        upload_source:
          type: string
        metadata: {}
        tags: {}
    VendorCreditLineItemRequest:
      type: object
      description: Serializer for vendor credit line items.
      properties:
        amount:
          type: integer
          minimum: 1
          description: Credit amount in cents for this line item
        sales_taxes:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: 'Tax array: [{''amount'': cents}]. Sum represents tax portion
            of line amount.'
        expense_account_identifier:
          nullable: true
          description: Account identifier for expense reversal posting (optional)
        memo:
          type: string
          description: Line item memo/description
        metadata:
          type: object
          additionalProperties: {}
          description: Line item metadata (max 10kb)
        reference_number:
          type: string
          description: Line item reference number
        tags:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Line item transaction tags
      required:
      - amount
    VendorCreditLineItemResponse:
      type: object
      description: Serializer for vendor credit line items in API responses.
      properties:
        amount:
          type: integer
          description: Credit amount in cents
          readOnly: true
        expense_account_identifier:
          allOf:
          - $ref: '#/components/schemas/AccountIdentifier'
          nullable: true
          readOnly: true
          description: Account identifier for expense reversal posting
        memo:
          type: string
        metadata: {}
        tags:
          type: array
          items:
            type: string
          description: Line item transaction tags
          readOnly: true
      required:
      - amount
      - expense_account_identifier
      - tags
    VendorCreditStats:
      type: object
      description: Statistics for vendor credits.
      properties:
        all:
          type: integer
          description: Total number of vendor credits
        unapplied:
          type: integer
          description: Number of unapplied credits (draft, sent, received, partially_applied)
        applied:
          type: integer
          description: Number of fully applied credits
      required:
      - all
      - applied
      - unapplied
    VendorDocumentUploadRequest:
      type: object
      description: Vendor specific document upload payload.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: vendor_document
        upload_source:
          type: string
        metadata: {}
        tags: {}
    VendorEmbedded:
      type: object
      description: Vendor details embedded in credit note and other response objects.
      properties:
        id:
          type: string
          format: uuid
          description: Vendor UUID
        external_id:
          type: string
          description: External vendor identifier
        display_name:
          type: string
          description: Vendor display name
      required:
      - display_name
      - external_id
      - id
    VendorRefund:
      type: object
      description: |-
        Comprehensive serializer for vendor refund responses.
        Includes all refund details plus related allocations and payments.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique vendor refund identifier
        vendor_id:
          type: string
          format: uuid
          readOnly: true
          description: UUID of the vendor who issued the refund
        vendor_name:
          type: string
          readOnly: true
          description: Vendor company name
        external_id:
          type: string
          description: Your external system identifier for idempotency
          maxLength: 255
        refund_type:
          enum:
          - overpayment
          - credit_balance
          - duplicate_payment
          - billing_error
          - goods_return
          - service_cancellation
          - other
          type: string
          x-spec-enum-id: 9e7c4f2adc5c33a3
          description: |-
            Refund type: overpayment, credit_balance, billing_error, goods_return, duplicate_payment, service_cancellation, other

            * `overpayment` - Overpayment Refund
            * `credit_balance` - Credit Balance Refund
            * `duplicate_payment` - Duplicate Payment
            * `billing_error` - Billing Error
            * `goods_return` - Goods Return
            * `service_cancellation` - Service Cancellation
            * `other` - Other
        reference_number:
          type: string
          description: External reference number for this refund
          maxLength: 100
        refund_date:
          type: string
          format: date
          description: Date when refund was issued
        expected_completion_date:
          type: string
          format: date
          nullable: true
          description: Expected date for refund completion
        total_refunded_amount:
          type: integer
          description: Total refunded amount in cents
          readOnly: true
        allocated_amount:
          type: integer
          description: Total allocated amount in cents
          readOnly: true
        unallocated_amount:
          type: integer
          description: Remaining unallocated amount in cents
          readOnly: true
        currency:
          enum:
          - EUR
          - GBP
          - USD
          - SEK
          - NOK
          - DKK
          - ISK
          - MYR
          - SGD
          type: string
          x-spec-enum-id: 7e6a70e4775b3009
          description: |-
            Refund currency (EUR, GBP, USD)

            * `EUR` - Euro
            * `GBP` - British Pound
            * `USD` - US Dollar
            * `SEK` - Swedish Krona
            * `NOK` - Norwegian Krone
            * `DKK` - Danish Krone
            * `ISK` - Icelandic Króna
            * `MYR` - Malaysian Ringgit
            * `SGD` - Singapore Dollar
        status:
          enum:
          - pending
          - partially_allocated
          - allocated
          - completed
          - cancelled
          type: string
          x-spec-enum-id: f9afcfd9cc5b0e7e
          description: |-
            Refund status: pending, partially_allocated, allocated, completed, cancelled (computed from allocations)

            * `pending` - Pending
            * `partially_allocated` - Partially Allocated
            * `allocated` - Allocated
            * `completed` - Completed
            * `cancelled` - Cancelled
        description:
          type: string
          description: Description of the refund reason or context
        memo:
          type: string
          description: Internal memo or notes
        reason:
          type: string
          description: Detailed explanation for the refund
          maxLength: 500
        metadata:
          description: Custom key-value pairs
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/VendorRefundAllocationResponse'
          readOnly: true
        vendor_refund_payments:
          type: array
          items:
            $ref: '#/components/schemas/VendorRefundPaymentResponse'
          readOnly: true
        document:
          allOf:
          - $ref: '#/components/schemas/DocumentFileUrl'
          readOnly: true
          description: Latest document linked to this vendor refund
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Refund creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
      required:
      - allocated_amount
      - allocations
      - created_at
      - document
      - id
      - total_refunded_amount
      - unallocated_amount
      - updated_at
      - vendor_id
      - vendor_name
      - vendor_refund_payments
    VendorRefundAllocationItemRequest:
      type: object
      description: |-
        Serializer for individual allocation items in vendor refund payment creation.

        This serializer handles the validation and conversion of allocation data
        for bills, payments, or credit allocations.
      properties:
        allocation_type:
          enum:
          - bill
          - payment
          - credit
          type: string
          x-spec-enum-id: 22d8aab8e694331c
          description: |-
            Type of allocation: 'bill' (apply to bill), 'payment' (refund payment), or 'credit' (credit balance)

            * `bill` - bill
            * `payment` - payment
            * `credit` - credit
        amount_cents:
          type: integer
          minimum: 1
          description: Allocation amount in cents (e.g., 50000 for £500.00)
        bill_id:
          type: string
          format: uuid
          nullable: true
          description: Bill ID (required for 'bill' allocation type)
        bill_payment_id:
          type: string
          format: uuid
          nullable: true
          description: Bill payment ID (required for 'payment' allocation type)
        description:
          type: string
          description: Description of the allocation
          maxLength: 500
        metadata:
          nullable: true
          description: Additional metadata for the allocation
      required:
      - allocation_type
      - amount_cents
    VendorRefundAllocationResponse:
      type: object
      description: Serializer for vendor refund allocation responses. All amounts
        in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique allocation identifier
        allocation_type:
          enum:
          - bill
          - payment
          - credit
          type: string
          x-spec-enum-id: 9a3c37d0b190f26e
          description: |-
            Type of allocation: bill, payment, or credit

            * `bill` - Applied to Bill
            * `payment` - Refund of Payment
            * `credit` - Credit Balance
        amount:
          type: integer
          description: Allocated amount in cents
          readOnly: true
        bill_id:
          type: string
          format: uuid
          description: Bill ID if allocated to bill
          readOnly: true
        bill_number:
          type: string
          description: Bill number if allocated to bill
          readOnly: true
        bill_outstanding_balance_cents:
          type: integer
          description: Bill outstanding balance in cents if allocated to bill
          readOnly: true
        bill_payment_id:
          type: string
          format: uuid
          description: Bill payment ID if allocated to payment
          readOnly: true
        allocation_date:
          type: string
          format: date-time
          description: When allocation was created
        description:
          type: string
          description: Allocation description or notes
          maxLength: 500
        metadata:
          description: Custom key-value pairs for allocation
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Allocation creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
        target_description:
          type: string
          readOnly: true
          description: Human-readable description of allocation target
      required:
      - amount
      - bill_id
      - bill_number
      - bill_outstanding_balance_cents
      - bill_payment_id
      - created_at
      - id
      - target_description
      - updated_at
    VendorRefundAllocationSummary:
      type: object
      description: Vendor refund allocation summary for bill detail view - shows vendor
        refunds allocated to this bill.
      properties:
        vendor_refund_id:
          type: string
          format: uuid
        reference_number:
          type: string
        amount_cents:
          type: integer
        allocated_at:
          type: string
          format: date-time
      required:
      - allocated_at
      - amount_cents
      - vendor_refund_id
    VendorRefundDocumentUploadRequest:
      type: object
      description: Vendor refund specific document upload payload.
      properties:
        file:
          type: string
          format: binary
          writeOnly: true
        document_type:
          type: string
          default: vendor_refund
        upload_source:
          type: string
        metadata: {}
        tags: {}
    VendorRefundPaymentCancelResponse:
      type: object
      description: Response serializer for vendor refund payment cancellation.
      properties:
        message:
          type: string
          description: Status message describing the cancellation result
        payment_id:
          type: string
          format: uuid
          description: UUID of the cancelled vendor refund payment
        refund_id:
          type: string
          format: uuid
          description: UUID of the associated vendor refund
        status:
          type: string
          description: Updated status of the vendor refund payment
        updated_at:
          type: string
          format: date-time
          description: Timestamp of the last payment update
      required:
      - message
      - payment_id
      - refund_id
      - status
      - updated_at
    VendorRefundPaymentCreateRequest:
      type: object
      description: |-
        Serializer for creating vendor refund payments with embedded allocations.

        This serializer handles the unified creation of vendor refunds, payments,
        and allocations in a single atomic operation.
      properties:
        vendor_id:
          type: string
          format: uuid
          description: UUID of the vendor issuing the refund
        total_amount_cents:
          type: integer
          minimum: 1
          description: Total refund amount in cents (e.g., 100000 for £1000.00)
        allocations:
          type: array
          items:
            $ref: '#/components/schemas/VendorRefundAllocationItemRequest'
          description: List of allocations for the refund
        external_id:
          type: string
          description: External system ID for idempotency
          maxLength: 255
        refund_type:
          enum:
          - overpayment
          - billing_error
          - goods_return
          - credit_balance
          - duplicate_payment
          - other
          type: string
          x-spec-enum-id: 38f88e0c97de179b
          default: overpayment
          description: |-
            Type of refund

            * `overpayment` - Overpayment
            * `billing_error` - Billing Error
            * `goods_return` - Goods Return
            * `credit_balance` - Credit Balance
            * `duplicate_payment` - Duplicate Payment
            * `other` - Other
        refund_date:
          type: string
          format: date
          description: Date of the refund (defaults to today)
        currency:
          type: string
          minLength: 1
          description: Currency code (defaults to vendor's currency)
          maxLength: 3
        description:
          type: string
          description: Refund description
        memo:
          type: string
          description: Internal memo
        reason:
          type: string
          description: Reason for the refund
          maxLength: 500
        metadata:
          nullable: true
          description: Additional structured data
        payment_method:
          enum:
          - bank_transfer
          - ach
          - wire
          - check
          - credit_card
          - cash
          - other
          type: string
          x-spec-enum-id: 1cd9444edaf0ad8b
          default: bank_transfer
          description: |-
            Payment method used for the refund

            * `bank_transfer` - Bank Transfer
            * `ach` - ACH Transfer
            * `wire` - Wire Transfer
            * `check` - Check
            * `credit_card` - Credit Card Reversal
            * `cash` - Cash
            * `other` - Other
        processor:
          enum:
          - stripe
          - wise
          - paypal
          - bank_transfer
          - internal
          type: string
          x-spec-enum-id: c841362fdd1cad7c
          default: bank_transfer
          description: |-
            Payment processor used

            * `stripe` - Stripe
            * `wise` - Wise (TransferWise)
            * `paypal` - PayPal
            * `bank_transfer` - Direct Bank Transfer
            * `internal` - Internal Processing
        payment_reference:
          type: string
          description: External payment reference number
          maxLength: 100
        processing_fee_cents:
          type: integer
          minimum: 0
          default: 0
          description: Processing fee in cents
      required:
      - total_amount_cents
      - vendor_id
    VendorRefundPaymentCreateResponse:
      type: object
      description: |-
        Serializer for vendor refund payment create/update responses.

        This serializer formats the response data for successful refund payment
        creation operations. Renamed from VendorRefundPaymentResponseSerializer
        to avoid naming conflict with vendor_refund_serializers.py.
      properties:
        refund:
          type: object
          additionalProperties: {}
          description: Complete refund information
        payment:
          type: object
          additionalProperties: {}
          nullable: true
          description: Payment information
        allocations:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: List of allocations created
      required:
      - allocations
      - payment
      - refund
    VendorRefundPaymentList:
      type: object
      description: |-
        Serializer for listing vendor refund payments.

        Provides a summary view of payments for list endpoints, optimized for
        performance with minimal related data.
        All amounts in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique vendor refund payment identifier
        refund_id:
          type: string
          format: uuid
          readOnly: true
          description: Parent vendor refund this payment belongs to
        vendor_id:
          type: string
          format: uuid
          readOnly: true
          description: Vendor providing this refund
        vendor_name:
          type: string
          readOnly: true
          description: Vendor display name
        payment_reference:
          type: string
          readOnly: true
          description: Payment reference number
        payment_method:
          type: string
          readOnly: true
          description: Payment method (BANK_TRANSFER, CHECK, CREDIT_CARD, etc.)
        processor:
          type: string
          readOnly: true
          description: Payment processor used
        refunded_amount_cents:
          type: integer
          readOnly: true
          description: Refunded amount in cents
        processing_fee_cents:
          type: integer
          readOnly: true
          description: Processing fee in cents
        net_amount_cents:
          type: integer
          readOnly: true
          description: Net amount after fees in cents
        currency:
          type: string
          readOnly: true
          description: Payment currency (e.g., GBP, EUR, USD)
        status:
          type: string
          readOnly: true
          description: Payment status (pending, processing, completed, failed, cancelled)
        payment_date:
          type: string
          format: date
          readOnly: true
          description: Date payment was received
        submitted_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          description: When payment was submitted for processing
        completed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          description: When payment was completed
        failed_at:
          type: string
          format: date-time
          readOnly: true
          nullable: true
          description: When payment failed
        failure_reason:
          type: string
          readOnly: true
          nullable: true
          description: Reason for payment failure
        reconciled_bank_transactions:
          type: array
          items:
            $ref: '#/components/schemas/EntityReconciliationDetail'
          readOnly: true
          description: Bank transactions this payment is reconciled to
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Payment record creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
      required:
      - completed_at
      - created_at
      - currency
      - failed_at
      - failure_reason
      - id
      - net_amount_cents
      - payment_date
      - payment_method
      - payment_reference
      - processing_fee_cents
      - processor
      - reconciled_bank_transactions
      - refund_id
      - refunded_amount_cents
      - status
      - submitted_at
      - updated_at
      - vendor_id
      - vendor_name
    VendorRefundPaymentResponse:
      type: object
      description: Serializer for vendor refund payment responses. All amounts in
        cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: Unique vendor refund payment identifier
        vendor_refund_id:
          type: string
          format: uuid
          readOnly: true
          description: ID of the vendor refund this payment belongs to
        payment_reference:
          type: string
          description: Your internal payment reference
          maxLength: 100
        processor_payment_id:
          type: string
          description: External processor payment ID
          maxLength: 255
        payment_date:
          type: string
          format: date
          description: Date when payment was made
        refunded_amount:
          type: integer
          description: Refunded amount in cents
          readOnly: true
        processing_fee:
          type: integer
          description: Processing fee in cents
          readOnly: true
        net_amount:
          type: integer
          description: Net amount after fees in cents
          readOnly: true
        payment_method:
          enum:
          - bank_transfer
          - ach
          - wire
          - check
          - credit_card
          - cash
          - other
          type: string
          x-spec-enum-id: 1cd9444edaf0ad8b
          description: |-
            Payment method: bank_transfer, ach, wire, check, credit_card, cash, other

            * `bank_transfer` - Bank Transfer
            * `ach` - ACH Transfer
            * `wire` - Wire Transfer
            * `check` - Check
            * `credit_card` - Credit Card Reversal
            * `cash` - Cash
            * `other` - Other
        processor:
          enum:
          - stripe
          - wise
          - paypal
          - bank_transfer
          - internal
          type: string
          x-spec-enum-id: c841362fdd1cad7c
          description: |-
            Payment processor: stripe, wise, paypal, bank_transfer, internal

            * `stripe` - Stripe
            * `wise` - Wise (TransferWise)
            * `paypal` - PayPal
            * `bank_transfer` - Direct Bank Transfer
            * `internal` - Internal Processing
        status:
          enum:
          - pending
          - processing
          - completed
          - failed
          - cancelled
          type: string
          x-spec-enum-id: 9c61eae888c009aa
          description: |-
            Payment status: pending, processing, completed, failed, cancelled

            * `pending` - Pending
            * `processing` - Processing
            * `completed` - Completed
            * `failed` - Failed
            * `cancelled` - Cancelled
        submitted_at:
          type: string
          format: date-time
          nullable: true
          description: When payment was submitted for processing
        completed_at:
          type: string
          format: date-time
          nullable: true
          description: When payment completed successfully
        failed_at:
          type: string
          format: date-time
          nullable: true
          description: When payment failed
        failure_reason:
          type: string
          description: Reason for payment failure
        description:
          type: string
          description: Payment description
        memo:
          type: string
          description: Internal memo
        metadata:
          description: Custom key-value pairs
        transaction_tags:
          description: Transaction tags for categorization
        reconciled_bank_transactions:
          type: array
          items:
            $ref: '#/components/schemas/EntityReconciliationDetail'
          readOnly: true
          description: Bank transactions this vendor refund payment is reconciled
            to
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: Payment creation timestamp
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: Last update timestamp
      required:
      - created_at
      - id
      - net_amount
      - processing_fee
      - reconciled_bank_transactions
      - refunded_amount
      - updated_at
      - vendor_refund_id
    VendorRefundReconciliationRequestRequest:
      type: object
      description: Request serializer for vendor refund payment reconciliation
      properties:
        notes:
          type: string
          description: Optional notes for the reconciliation
          maxLength: 500
        evidence:
          type: object
          additionalProperties: {}
          description: Supporting evidence for the reconciliation
        created_by:
          enum:
          - api
          - manual
          - auto
          - import
          type: string
          x-spec-enum-id: 5993daf453316fc6
          default: api
          description: |-
            Source of reconciliation (api, manual, auto, import)

            * `api` - api
            * `manual` - manual
            * `auto` - auto
            * `import` - import
        vendor_refund_id:
          type: string
          format: uuid
          description: Vendor refund ID to reconcile
        payment_method:
          enum:
          - bank_transfer
          - credit_card
          - debit_card
          - ach
          - check
          - cash
          - wire
          - paypal
          - stripe
          - other
          type: string
          x-spec-enum-id: 6a4918e6dc1589b2
          default: bank_transfer
          description: |-
            Payment method for the reconciliation

            * `bank_transfer` - bank_transfer
            * `credit_card` - credit_card
            * `debit_card` - debit_card
            * `ach` - ach
            * `check` - check
            * `cash` - cash
            * `wire` - wire
            * `paypal` - paypal
            * `stripe` - stripe
            * `other` - other
        amount_cents:
          type: integer
          minimum: 1
          nullable: true
          description: Amount to reconcile in cents. If not provided, uses min(refund_amount,
            bank_remaining).
      required:
      - vendor_refund_id
    VendorRefundStats:
      type: object
      description: Statistics for vendor refunds.
      properties:
        all:
          type: integer
          description: Total number of vendor refunds
        pending:
          type: integer
          description: 'Number of pending refunds (status=pending). Non-pending statuses:
            partially_allocated, allocated, completed, cancelled'
      required:
      - all
      - pending
    VendorRefundUnreconciliationRequestRequest:
      type: object
      description: Request serializer for vendor refund payment unreconciliation
      properties:
        vendor_refund_id:
          type: string
          format: uuid
          description: Vendor refund ID to unreconcile
      required:
      - vendor_refund_id
    VendorRequest:
      type: object
      description: Serializer for vendor objects returned by the vendors list endpoint
      properties:
        external_id:
          type: string
          description: Your unique identifier for this vendor (used for idempotency)
          maxLength: 255
        individual_name:
          type: string
          description: Vendor individual name (for sole traders/freelancers)
          maxLength: 255
        company_name:
          type: string
          description: Registered company name (for limited companies)
          maxLength: 255
        email:
          type: string
          format: email
          description: Primary email address for vendor communications
          maxLength: 254
    WriteOff:
      type: object
      description: Response serializer in provider shape. All amounts in cents.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        invoice_id:
          type: string
          format: uuid
          readOnly: true
          description: Invoice that was written off
        external_id:
          type: string
          description: Your external identifier for this write-off
          maxLength: 255
        amount:
          type: integer
          description: Write-off amount in cents
          readOnly: true
        memo:
          type: string
          description: Reason or description for the write-off
        destination_account:
          type: object
          additionalProperties: {}
          nullable: true
          readOnly: true
          description: Bad debt expense account where write-off was posted
        write_off_at:
          type: string
          format: date-time
          description: Date/time when write-off was recorded
        transaction_tags:
          type: array
          items: {}
          readOnly: true
          description: Tags associated with this write-off
      required:
      - amount
      - destination_account
      - id
      - invoice_id
      - transaction_tags
      - write_off_at
    WriteOffSummary:
      type: object
      description: Write-off summary for invoice detail view.
      properties:
        write_off_id:
          type: string
          format: uuid
        amount_cents:
          type: integer
        reason:
          type: string
        status:
          type: string
        write_off_at:
          type: string
          format: date-time
      required:
      - amount_cents
      - reason
      - status
      - write_off_at
      - write_off_id
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: 'Basic authentication for OAuth2 token endpoint. Use partner_uuid:api_key
        as username:password. Example: Authorization: Basic base64(partner_uuid:api_key)'
    BearerBusinessScoped:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Business-scoped JWT Bearer token. Obtain via POST /v1/platform/{business_id}/oauth2/token/
        using a partner Bearer token. Only valid for endpoints whose URL contains
        that business_id.
    BearerUnscoped:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'Partner (unscoped) JWT Bearer token. Obtain via POST /v1/platform/oauth2/token
        with Basic auth (partner_uuid:api_key). Use header: Authorization: Bearer
        {access_token}'
    BusinessScopedJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |-
        Business-scoped JWT token. Token payload includes `business_id` to automatically scope requests. Format: `Bearer <your-jwt-token>`

        **Use this for**: Business-specific operations where the business context is embedded in the token.
    DirectSMEPortalSessionAuth:
      type: apiKey
      in: cookie
      name: sessionid
      description: Django session-based authentication for Direct SME Portal users
    FinancialAdminAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT Bearer token authentication for Financial Admin Portal users
        (accountants/bookkeepers)
    InternalAdminAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT Bearer token authentication for Internal Admin users (Thred
        staff)
    PartnerJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |-
        Partner-level JWT token (unscoped). Token payload includes `partner_id`. Business access is validated via partner ownership. Format: `Bearer <your-jwt-token>`

        **Use this for**: Multi-business operations where the business_id is specified in the URL and partner has access to multiple businesses.
    PartnerPortalAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT Bearer token authentication for Partner Portal users
    basicAuth:
      type: http
      scheme: basic
    cookieAuth:
      type: apiKey
      in: cookie
      name: sessionid
