openapi: 3.0.1
info:
  title: Elevate Customer and Sites API
  description: >
    ### Customer and Site Management


    Provides read & write access to customer and site entities.


    #### Definitions

    * Customer - the primary entity within Elevate to represent the person or
    company who is contracted with a Contract Owner for the provision of
    products or services

    * Site - within each Customer, there are one or more Sites to represent the
    physical locations of the Customer


    Products and services are associated to the Sites as inventory items. Sites
    can be setup to receive invoices individually or to consolidate invoices to
    a particular site or sites
  version: '1.41'
servers:
  - url: https://rest.elevatebilling.com/v1
tags:
  - name: customers
    description: >-
      Customers represent the person or company contracted to receive products
      or services
  - name: sites
    description: Sites represent the physical locations for each Customer
paths:
  /customers:
    get:
      tags:
        - customers
      summary: Get a list of available customers
      operationId: getCustomers
      x-si-permissions:
        - VIEW_CUSTOMER
        - VIEW_SITE
      security:
        - bearerAuth: []
      x-si-filterable: true
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/sort'
        - $ref: '#/components/parameters/fields'
        - name: contractOwnerId
          in: query
          description: Filter by contract owner
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: customerName
          in: query
          description: Filter by customer name
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: customerType
          in: query
          description: Filter by customer type
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: customerAccountNumber
          in: query
          description: Filter by customer account number
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: billingCycleId
          in: query
          description: Filter by billing cycle
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: startDate
          in: query
          description: Filter by start date
          schema:
            $ref: '#/components/schemas/DateFilterParam'
          required: false
        - name: endDate
          in: query
          description: Filter by end date
          schema:
            $ref: '#/components/schemas/DateFilterParam'
          required: false
        - name: createdDate
          in: query
          description: Filter by created date/time
          schema:
            $ref: '#/components/schemas/DateTimeFilterParam'
          required: false
        - name: updatedDate
          in: query
          description: Filter by updated date/time
          schema:
            $ref: '#/components/schemas/DateTimeFilterParam'
          required: false
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Customer'
        '400':
          description: Bad Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
    post:
      tags:
        - customers
      summary: Create a new customer and primary site
      operationId: createCustomer
      x-si-permissions:
        - CREATE_CUSTOMER
        - CREATE_SITE
      x-si-apply-impact-of-change: true
      security:
        - bearerAuth: []
      requestBody:
        description: New customer and default site
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Customer'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '400':
          description: Bad Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
    head:
      tags:
        - customers
      summary: Check if customer exists
      operationId: checkCustomer
      x-si-permissions:
        - VIEW_CUSTOMER
      security:
        - bearerAuth: []
      parameters:
        - name: contractOwnerId
          in: query
          description: Filter by contract owner
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: customerName
          in: query
          description: Filter by customer name
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: customerType
          in: query
          description: Filter by customer type
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: customerAccountNumber
          in: query
          description: Filter by customer account number
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: billingCycleId
          in: query
          description: Filter by billing cycle
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: startDate
          in: query
          description: Filter by start date
          schema:
            $ref: '#/components/schemas/DateFilterParam'
          required: false
        - name: endDate
          in: query
          description: Filter by end date
          schema:
            $ref: '#/components/schemas/DateFilterParam'
          required: false
      responses:
        '200':
          description: Exists
          content: {}
        '400':
          description: Invalid Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
  /customers/{customer_id}:
    get:
      tags:
        - customers
      summary: Get a specific customer
      operationId: getCustomer
      x-si-permissions:
        - VIEW_CUSTOMER
        - VIEW_SITE
      security:
        - bearerAuth: []
      parameters:
        - name: customer_id
          in: path
          description: Customer identifier
          required: true
          schema:
            $ref: '#/components/schemas/IdParam'
      responses:
        '200':
          description: Customer found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '400':
          description: Bad Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
    patch:
      tags:
        - customers
      summary: Update a customer
      operationId: updateCustomer
      x-si-json-patch: true
      x-si-allow-patch:
        - /customer(Name|Type|AccountNumber)
        - /(start|end)Date
        - /contractTerm
        - /contractTermStartDate
        - /externalCommissionAgentId
        - /onlineBillingRequired
        - /onlineEmailAddress
        - /sendWelcomeEmailOn
        - /billingCycleId
        - /creditThreshold
        - /tripwireId
        - /customerIsVip
        - /customerMarker
        - /customerContacts/.*
        - /assignedCustomFields.*
        - /assignedCustomFields/.*/value
      x-si-requires-permission-to-update: true
      x-si-permissions:
        - UPDATE_CUSTOMER
        - UPDATE_SITE
      security:
        - bearerAuth: []
      parameters:
        - name: customer_id
          in: path
          description: Customer identifier
          required: true
          schema:
            $ref: '#/components/schemas/IdParam'
        - name: cascade_end_date
          in: header
          description: >-
            A boolean flag to specify that the end date is to be cascaded down
            to all sites / inventories. An end date must be supplied in the
            patch for this flag to apply
          required: false
          schema:
            $ref: '#/components/schemas/BooleanFilterParam'
      requestBody:
        description: A set of JSONPatch operations to be performed
        content:
          application/json-patch+json:
            schema:
              $ref: '#/components/schemas/PatchRequest'
            examples:
              ChangeName:
                value:
                  - op: replace
                    path: /name
                    value: Supreme Wire Telecoms Ltd
              EndDate:
                value:
                  - op: replace
                    path: /endDate
                    value: '2023-01-30'
              ChangeBillingCycle:
                value:
                  - op: replace
                    path: /billingCycleId
                    value: 2
              ChangeBillingCycle&EndDate:
                value:
                  - op: replace
                    path: /billingCycleId
                    value: 2
                  - op: replace
                    path: /endDate
                    value: '2023-01-30'
              AddCustomerContact:
                value:
                  - op: add
                    path: /customerContacts/-
                    value:
                      contactName: string
                      contactTelephoneNumber: string
                      contactAlternativeTelephoneNumber: string
                      contactEmailAddress: email@email.com
                      contactRole: ACCOUNTS
                      receiveInvoiceBy: EMAIL
                      receiveInvoiceSummaryBy: EMAIL
                      receiveElectronicSummaryReports: true
                      emailSuspended: false
                      contactNameToAppearOnInvoice: false
                      receiveEmailFraudAlert: false
                      receiveSmsFraudAlert: false
              UpdateCustomFieldValue:
                value:
                  - op: replace
                    path: /assignedCustomFields/0/value
                    value: New custom field value
              ClearCustomFieldValue:
                value:
                  - op: replace
                    path: /assignedCustomFields/0/value
                    value: null
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '400':
          description: Invalid Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
  /sites:
    get:
      tags:
        - sites
      summary: Get a list of available sites
      operationId: getSites
      x-si-permissions:
        - VIEW_SITE
      security:
        - bearerAuth: []
      x-si-filterable: true
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/sort'
        - $ref: '#/components/parameters/fields'
        - name: customerId
          in: query
          description: Filter by customer
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: siteName
          in: query
          description: Filter by site name
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: siteReference
          in: query
          description: Filter by site reference
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: createdDate
          in: query
          description: Filter by created date/time
          schema:
            $ref: '#/components/schemas/DateTimeFilterParam'
          required: false
        - name: updatedDate
          in: query
          description: Filter by updated date/time
          schema:
            $ref: '#/components/schemas/DateTimeFilterParam'
          required: false
        - name: mandateStatus
          in: query
          description: Filter by mandate status
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: mandateCreatedDate
          in: query
          description: Filter by mandate created date
          schema:
            $ref: '#/components/schemas/DateFilterParam'
          required: false
        - name: mandateUpdatedDate
          in: query
          description: Filter by mandate updated date
          schema:
            $ref: '#/components/schemas/DateFilterParam'
          required: false
        - name: mandateReference
          in: query
          description: Filter by mandate reference
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Site'
        '400':
          description: Bad Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
    post:
      tags:
        - sites
      summary: Create a new site
      operationId: createSite
      x-si-permissions:
        - CREATE_SITE
      x-si-apply-impact-of-change: true
      security:
        - bearerAuth: []
      requestBody:
        description: New site
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Site'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Site'
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Site'
        '400':
          description: Bad Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
    head:
      tags:
        - sites
      summary: Check if site exists
      operationId: checkSite
      x-si-response-headers: true
      x-si-permissions:
        - VIEW_SITE
      security:
        - bearerAuth: []
      parameters:
        - name: customerId
          in: query
          description: Filter by customer
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: invoiceTemplateId
          in: query
          description: Filter by invoice template id
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: billingCycleId
          in: query
          description: Filter by billing cycle id
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: siteName
          in: query
          description: Filter by site name
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: siteReference
          in: query
          description: Filter by site reference
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: activeSites
          in: query
          description: >-
            Filter to exclude sites that are ended (end date is before today).
            The value is either true or false
          schema:
            $ref: '#/components/schemas/StringFilterParam'
          required: false
        - name: contractOwnerSubBrandId
          in: query
          description: Filter by contract owner sub brand identifier
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
        - name: adhocBillRunId
          in: query
          description: Filter by adhoc bill run identifier
          schema:
            $ref: '#/components/schemas/IdFilterParam'
          required: false
      responses:
        '200':
          description: Exists
          content: {}
          headers:
            X-Total-Count:
              schema:
                type: integer
                description: Total number of sites
        '400':
          description: Invalid Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
  /sites/{site_id}:
    get:
      tags:
        - sites
      summary: Get a specific site
      operationId: getSite
      x-si-permissions:
        - VIEW_SITE
      security:
        - bearerAuth: []
      parameters:
        - name: site_id
          in: path
          description: Site identifier
          required: true
          schema:
            $ref: '#/components/schemas/IdParam'
      responses:
        '200':
          description: Site found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Site'
        '400':
          description: Bad Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
    patch:
      tags:
        - sites
      summary: Update a site
      operationId: updateSite
      x-si-json-patch: true
      x-si-allow-patch:
        - /site(Name|Reference)
        - /(start|end)Date
        - /repaymentPlanAmount
        - /repaymentPlanRemainingPeriods
        - /siteAddress/businessName
        - /siteAddress/address[0-9]*
        - /siteAddress/town
        - /siteAddress/county
        - /siteAddress/postcode
        - /siteAddress/country
        - /siteInvoiceDetails/electronicSummaryTemplateIds/.*
        - /siteInvoiceDetails/invoiceSummaryTemplateComponents/.*
        - /siteInvoiceDetails/invoice(Template|SummaryTemplate)Id
        - /siteInvoiceDetails/invoiceAddress.businessName
        - /siteInvoiceDetails/invoiceAddress.address[0-9]*
        - /siteInvoiceDetails/invoiceAddress.town
        - /siteInvoiceDetails/invoiceAddress.county
        - /siteInvoiceDetails/invoiceAddress.postcode
        - /siteInvoiceDetails/invoiceAddress.country
        - /siteInvoiceDetails/invoiceNotes
        - /siteInvoiceDetails/accountPackageReference
        - /siteInvoiceDetails/payment(Method|TermsInDays)
        - /siteInvoiceDetails/preferredPaymentDay
        - /siteInvoiceDetails/mandateReference
        - /siteInvoiceDetails/thirdPartyCustomerReference
        - /siteInvoiceDetails/mandateStatus
        - /siteInvoiceDetails/directDebitReference
        - /siteInvoiceDetails/account(Name|Number)
        - /siteInvoiceDetails/sortCode
        - /siteInvoiceDetails/purchaseOrderNumber
        - /siteInvoiceDetails/taxExempt
        - /siteInvoiceDetails/taxRegistrationNumber
        - /siteContacts/.*
        - /assignedCustomFields.*
        - /assignedCustomFields/.*/value
      x-si-requires-permission-to-update: true
      x-si-permissions:
        - UPDATE_SITE
      x-si-apply-impact-of-change: true
      security:
        - bearerAuth: []
      parameters:
        - name: site_id
          in: path
          description: Site identifier
          required: true
          schema:
            $ref: '#/components/schemas/IdParam'
        - name: cascade_end_date
          in: header
          description: >-
            A boolean flag to specify that the end date is to be cascaded down
            to all inventories. An end date must be supplied in the patch for
            this flag to apply
          required: false
          schema:
            $ref: '#/components/schemas/BooleanFilterParam'
      requestBody:
        description: A set of JSONPatch operations to be performed
        content:
          application/json-patch+json:
            schema:
              $ref: '#/components/schemas/PatchRequest'
            examples:
              ChangeName:
                value:
                  - op: replace
                    path: /name
                    value: Head Office
              EndDate:
                value:
                  - op: replace
                    path: /endDate
                    value: '2023-01-30'
              ChangeSiteReference&EndDate:
                value:
                  - op: replace
                    path: /siteReference
                    value: GLDTELCO123
                  - op: replace
                    path: /endDate
                    value: '2023-01-30'
              SetRepaymentPlan:
                value:
                  - op: replace
                    path: /repaymentPlanAmount
                    value: 24.99
                  - op: replace
                    path: /repaymentPlanRemainingPeriods
                    value: 12
              AddSiteContact:
                value:
                  - op: add
                    path: /siteContacts/-
                    value:
                      contactName: string
                      contactTelephoneNumber: string
                      contactAlternativeTelephoneNumber: string
                      contactEmailAddress: email@email.com
                      contactRole: ACCOUNTS
                      receiveInvoiceBy: EMAIL
                      receiveInvoiceSummaryBy: EMAIL
                      receiveElectronicSummaryReports: true
                      emailSuspended: false
                      contactNameToAppearOnInvoice: false
                      receiveEmailFraudAlert: false
                      receiveSmsFraudAlert: false
              ChangeFistSiteContact:
                value:
                  - op: replace
                    path: /siteContacts/0
                    value:
                      contactName: string
                      contactTelephoneNumber: string
                      contactAlternativeTelephoneNumber: string
                      contactEmailAddress: email@email.com
                      contactRole: ACCOUNTS
                      receiveInvoiceBy: EMAIL
                      receiveInvoiceSummaryBy: EMAIL
                      receiveElectronicSummaryReports: true
                      emailSuspended: false
                      contactNameToAppearOnInvoice: false
                      receiveEmailFraudAlert: false
                      receiveSmsFraudAlert: false
              UpdateCustomFieldValue:
                value:
                  - op: replace
                    path: /assignedCustomFields/0/value
                    value: New custom field value
              ClearCustomFieldValue:
                value:
                  - op: replace
                    path: /assignedCustomFields/0/value
                    value: null
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Site'
        '400':
          description: Invalid Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
        '404':
          description: Not Found
          content: {}
  /customer-billing-summaries:
    get:
      tags:
        - customers
      summary: Returns billing summary information
      description: >-
        Returns billing summary information for customers including open vs
        previous bill run values
      operationId: getCustomerBillingSummary
      x-si-permissions:
        - VIEW_CUSTOMER
      x-si-filterable: true
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/sort'
        - $ref: '#/components/parameters/fields'
        - name: customerId
          in: query
          description: Filter by customer
          required: false
          schema:
            $ref: '#/components/schemas/IdFilterParam'
        - name: valueDifference
          in: query
          description: >-
            Filter by the difference (absolute value) between the previous and
            the open bill run value
          required: false
          schema:
            $ref: '#/components/schemas/StringFilterParam'
        - name: percentageDifference
          in: query
          description: >-
            Filter by the difference (as percentage) between the previous and
            the open bill run value
          required: false
          schema:
            $ref: '#/components/schemas/StringFilterParam'
        - name: ratingStatus
          in: query
          description: Filter by rating status
          required: false
          schema:
            $ref: '#/components/schemas/StringFilterParam'
        - name: billingStatus
          in: query
          description: Filter by customer billing status
          required: false
          schema:
            $ref: '#/components/schemas/StringFilterParam'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CustomerBillingSummary'
        '400':
          description: Bad Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
  /customer-usage-data:
    get:
      tags:
        - customers
      summary: Returns usage data information for a customer
      operationId: getCustomerUsageData
      x-si-permissions:
        - VIEW_CUSTOMER_USAGE
      x-si-filterable: true
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/page'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/sort'
        - $ref: '#/components/parameters/fields'
        - name: customerId
          in: query
          description: Filter by customer id
          required: false
          schema:
            $ref: '#/components/schemas/IdFilterParam'
        - name: siteId
          in: query
          description: Filter by site id
          required: false
          schema:
            $ref: '#/components/schemas/IdFilterParam'
        - name: billRunId
          in: query
          description: Filter by bill run id
          required: false
          schema:
            $ref: '#/components/schemas/IdFilterParam'
        - name: productReference
          in: query
          description: Filter by product reference
          required: false
          schema:
            $ref: '#/components/schemas/StringFilterParam'
        - name: serviceId
          in: query
          description: Filter by serviceId
          required: false
          schema:
            $ref: '#/components/schemas/StringFilterParam'
        - name: eventDateFrom
          in: query
          description: Filter based on events from this date
          required: false
          schema:
            $ref: '#/components/schemas/DateTimeFilterParam'
        - name: eventDateTo
          in: query
          description: Filter based on events until this date
          required: false
          schema:
            $ref: '#/components/schemas/DateTimeFilterParam'
        - name: destination
          in: query
          description: Filter by destination/origin
          required: false
          schema:
            $ref: '#/components/schemas/StringFilterParam'
        - name: excludeZeroValueRecords
          in: query
          description: Filter out zero value entries
          required: false
          schema:
            $ref: '#/components/schemas/BooleanFilterParam'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CustomerUsageData'
        '400':
          description: Bad Request
          content: {}
        '401':
          description: Unauthorized
          content: {}
        '403':
          description: Forbidden
          content: {}
components:
  schemas:
    Site:
      type: object
      required:
        - customerId
        - siteName
        - siteReference
        - startDate
        - siteAddress
        - siteContacts
      x-si-no-change-allowed-in-finalised-bill-run: |
        fields = { "customerId" }
      x-si-class-validation: >
        @OnlyOneRequired(fields = { "siteInvoiceDetails",
        "siteIdReceivingInvoice" })

        @After(first = "endDate", second = "startDate")

        @RequiredWhenNotNull.List({
            @RequiredWhenNotNull(fieldName = "repaymentPlanAmount", dependFieldName = "repaymentPlanRemainingPeriods"),
            @RequiredWhenNotNull(fieldName = "repaymentPlanRemainingPeriods", dependFieldName = "repaymentPlanAmount")
        })
      properties:
        id:
          description: Site identifier
          type: integer
          readOnly: true
          format: int64
          example: 1
        customerId:
          description: Customer identifier - set to 0 when creating a new customer
          type: integer
          format: int64
          example: 0
        siteName:
          type: string
          description: Site name
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        siteReference:
          type: string
          description: Site reference
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        startDate:
          description: Site start date
          type: string
          format: date
        endDate:
          description: Site end date
          type: string
          format: date
        createdDate:
          readOnly: true
          description: Site created date
          type: string
          format: date-time
        updatedDate:
          readOnly: true
          description: Site updated date
          type: string
          format: date-time
        siteAddress:
          $ref: '#/components/schemas/Address'
        siteInvoiceDetails:
          $ref: '#/components/schemas/SiteInvoiceDetails'
        siteIdReceivingInvoice:
          description: >-
            Identifier of another site that receives the invoices if no invoice
            details provided for this site
          type: integer
          format: int64
          example: 1
        siteContacts:
          type: array
          minLength: 1
          items:
            $ref: '#/components/schemas/ContactDetails'
        repaymentPlanAmount:
          description: >-
            Repayment plan period amount in major currency (e.g
            pounds/dollars/euros)
          type: number
          format: decimal
          minimum: 1
          maximum: 100000
        repaymentPlanRemainingPeriods:
          description: repayment plan remaining periods (typically in months)
          type: integer
          format: int64
          maximum: 240
          minimum: 0
          example: 0
        assignedCustomFields:
          type: array
          items:
            $ref: '#/components/schemas/AssignedCustomField'
          example:
            - customFieldDefinitionId: 102
              label: Customer Tier
              value: Gold
    ContactDetails:
      type: object
      required:
        - contactName
        - contactRole
      x-si-class-validation: |
        @RequiredWhen.List({
            @RequiredWhen(fieldName="contactNameToAppearOnInvoice",fieldValue="true",dependFieldName="receiveInvoiceBy"),
            @RequiredWhen(fieldName="receiveInvoiceBy",fieldValue="EMAIL",dependFieldName="contactEmailAddress"),
            @RequiredWhen(fieldName="receiveInvoiceBy",fieldValue="EMAIL_AND_POST",dependFieldName="contactEmailAddress"),
            @RequiredWhen(fieldName="receiveInvoiceSummaryBy",fieldValue="EMAIL",dependFieldName="contactEmailAddress"),
            @RequiredWhen(fieldName="receiveInvoiceSummaryBy",fieldValue="EMAIL_AND_POST",dependFieldName="contactEmailAddress"),
            @RequiredWhen(fieldName="receiveElectronicSummaryReports",fieldValue="true",dependFieldName="contactEmailAddress")
        })
      properties:
        id:
          description: Contact identifier
          type: integer
          readOnly: true
          format: int64
          example: 1
        contactName:
          type: string
          description: Contact name
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        contactTelephoneNumber:
          type: string
          description: Contact telephone number
          minLength: 4
          maxLength: 100
          pattern: ^$|[a-zA-Z0-9\p{L}\s()@&.,-_£|]{4,100}
        contactAlternativeTelephoneNumber:
          type: string
          description: Contact alternative telephone number
          minLength: 4
          maxLength: 100
          pattern: ^$|[a-zA-Z0-9\p{L}\s()@&.,-_£|]{4,100}
        contactEmailAddress:
          description: Contact email address
          $ref: '#/components/schemas/EmailAddress'
        contactRole:
          $ref: '#/components/schemas/ContactRole'
        receiveInvoiceBy:
          $ref: '#/components/schemas/ReceiveInvoiceBy'
        receiveInvoiceSummaryBy:
          $ref: '#/components/schemas/ReceiveInvoiceSummaryBy'
        receiveElectronicSummaryReports:
          description: Will receive electronic summary reports
          type: boolean
        emailSuspended:
          description: Whether the contact is unable to receive emails
          type: boolean
          default: false
        contactNameToAppearOnInvoice:
          type: boolean
          description: >-
            Only 1 contact per site can be set to true. If unspecified, this
            will be defaulted to the 1st contact. If specified for a different
            contact, it will be set to false for the previous one
          default: false
        receiveEmailFraudAlert:
          type: boolean
          description: Will receive a fraud alert by email
          default: false
        receiveSmsFraudAlert:
          type: boolean
          description: Will receive a fraud alert by SMS
          default: false
    SiteInvoiceDetails:
      description: Invoice details if this site should receive invoices
      type: object
      required:
        - invoiceTemplateId
        - paymentMethod
      properties:
        invoiceSummaryTemplateId:
          description: Invoice summary template identifier - set on creation of site only
          type: integer
          format: int64
        invoiceTemplateId:
          description: Invoice template identifier - set on creation of site only
          type: integer
          format: int64
        electronicSummaryTemplateIds:
          description: >-
            List of electronic summary template identifiers associated with this
            site
          type: array
          minLength: 0
          items:
            description: Electronic summary template identifier
            type: integer
            format: int32
            example: 123
        invoiceSummaryTemplateComponents:
          description: >-
            List of invoice summary template components associated with this
            site
          type: array
          minLength: 0
          items:
            $ref: '#/components/schemas/InvoiceSummaryTemplateComponent'
        invoiceAddress:
          $ref: '#/components/schemas/Address'
        accountPackageReference:
          type: string
          description: Account package reference
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        paymentTermsInDays:
          description: >-
            Payment terms in days, used to derive the invoice due date. Either
            paymentTermsInDays or preferredPaymentDay are required
          type: integer
          format: int32
          maximum: 400
          minimum: 0
        preferredPaymentDay:
          description: >-
            Preferred payment day of month, used to derive the invoice due date.
            When automated, it will be used to collect money on that date.
            Either paymentTermsInDays or preferredPaymentDay are required
          type: integer
          format: int32
          maximum: 28
          minimum: 1
        paymentMethod:
          $ref: '#/components/schemas/PaymentMethod'
        mandateStatus:
          readOnly: true
          type: string
          description: Mandate status
          minLength: 1
          maxLength: 50
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        mandateCreatedDate:
          readOnly: true
          description: Site invoice mandate created date
          type: string
          format: date-time
        mandateUpdatedDate:
          readOnly: true
          description: Site invoice mandate updated date
          type: string
          format: date-time
        mandateReference:
          type: string
          description: >-
            Required when the paymentType is an integrated one, for example
            GO_CARDLESS, FINASTRA or STRIPE. If GO_CARDLESS, only accepted
            Created, Pending Submission, Submitted, Active, Reinstated, Customer
            approval granted and Customer approval skipped
          minLength: 1
          maxLength: 100
        thirdPartyCustomerReference:
          type: string
          description: >-
            Reference to a customer in a third party system. For example, Stripe
            Customer ID (mandatory if a Stripe mandate is provided), or optional
            references like GO_CARDLESS Customer Reference or FINASTRA Account
            Number
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        directDebitReference:
          type: string
          description: Direct debit reference
          minLength: 1
          maxLength: 20
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        accountName:
          type: string
          description: Bank account name
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        accountNumber:
          description: Bank account number
          type: string
          minLength: 8
          maxLength: 30
          pattern: '[0-9]+'
        sortCode:
          description: Sort code
          type: string
          minLength: 6
          maxLength: 6
          pattern: '[0-9]+'
        purchaseOrderNumber:
          type: string
          description: Purchase order number
          minLength: 1
          maxLength: 50
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        invoiceNotes:
          type: string
          description: Notes to appear on invoices addressed to this site
          minLength: 1
          maxLength: 250
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        taxExempt:
          description: Site is tax exempt
          type: boolean
          default: false
        taxRegistrationNumber:
          description: Tax registration number
          type: string
          minLength: 0
          maxLength: 50
          pattern: ([A-Za-z0-9\p{L}\s]*)
    InvoiceSummaryTemplateComponent:
      type: object
      required:
        - id
        - positionInTemplate
      properties:
        id:
          description: Invoice summary component identifier
          type: integer
          readOnly: true
          format: int64
          example: 1
        positionInTemplate:
          description: Position of the component within the invoice summary template
          type: integer
          readOnly: true
          format: int64
          example: 1
    Customer:
      required:
        - contractOwnerId
        - customerType
        - customerName
        - customerAccountNumber
        - startDate
        - billingCycleId
        - sites
      type: object
      x-si-no-change-allowed-in-finalised-bill-run: |
        fields = { "contractOwnerId" }
      x-si-class-validation: >
        @After.List({
            @After(first = "endDate", second = "startDate"),
            @After(first = "contractTermStartDate", second = "startDate")
        })

        @RequiredWhen(fieldName="onlineBillingRequired",fieldValue="true",dependFieldName="sendWelcomeEmailOn")

        @RequiredWhenNotNull.List({
            @RequiredWhenNotNull(fieldName = "contractTerm", dependFieldName = "contractTermStartDate"),
            @RequiredWhenNotNull(fieldName = "contractTermStartDate", dependFieldName = "contractTerm")
        })
      properties:
        id:
          description: Customer identifier
          type: integer
          readOnly: true
          format: int64
          example: 1
        contractOwnerId:
          description: Contract Owner Identifier
          type: integer
          format: int32
          x-si-validation: '@ValidId'
        contractOwnerSubBrandId:
          description: >-
            Contract owner sub brand identifier, if not specified then the
            default will be used
          type: integer
          format: int32
          x-si-validation: '@ValidId'
        customerType:
          $ref: '#/components/schemas/CustomerType'
        customerName:
          type: string
          description: Customer Name
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        customerAccountNumber:
          type: string
          description: Customer account number
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        startDate:
          description: Customer start date
          type: string
          format: date
        endDate:
          description: Customer end date
          type: string
          format: date
        createdDate:
          readOnly: true
          description: Customer created date
          type: string
          format: date-time
        updatedDate:
          readOnly: true
          description: Customer updated date
          type: string
          format: date-time
        contractTerm:
          description: >-
            Contract term in months if applicable - requires contract term start
            date
          type: integer
          format: int32
        contractTermStartDate:
          description: >-
            Start date of contract term if applicable - required with contract
            term
          type: string
          format: date
        customerIsVip:
          description: >-
            Customer is marked as VIP (deprecated - please use customerMarker
            instead)
          type: boolean
          default: false
        customerMarker:
          description: Customer is marked, e.g. VIP, Vulnerable, etc
          type: boolean
          default: false
        externalCommissionAgentId:
          description: External commission agent identifier
          type: integer
          format: int64
          x-si-validation: '@ValidId'
          example: 1
        onlineBillingRequired:
          description: Online billing required
          type: boolean
          default: false
        onlineEmailAddress:
          description: Online email address
          $ref: '#/components/schemas/EmailAddress'
        sendWelcomeEmailOn:
          description: Send welcome email on this date
          type: string
          format: date
        billingCycleId:
          description: Billing cycle identifier
          type: integer
          format: int64
          x-si-validation: '@ValidId'
          example: 1
        sites:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            $ref: '#/components/schemas/Site'
        creditThreshold:
          description: Customer credit threshold
          type: number
          example: 100
          minimum: 0
          maximum: 100000000000000000
        tripwireId:
          description: Tripwire plan identifier
          type: integer
          format: int64
          x-si-validation: '@ValidId'
        customerContacts:
          type: array
          items:
            $ref: '#/components/schemas/ContactDetails'
        assignedCustomFields:
          type: array
          items:
            $ref: '#/components/schemas/AssignedCustomField'
          example:
            - customFieldDefinitionId: 102
              label: Customer Tier
              value: Gold
    CustomerBillingSummary:
      type: object
      properties:
        customerId:
          type: integer
          description: Customer identifier
          format: int64
          readOnly: true
          example: 1
        billingStatus:
          $ref: '#/components/schemas/CustomerBillingStatus'
        ratingStatus:
          $ref: '#/components/schemas/CustomerRatingStatus'
        openBillRunValue:
          type: number
          description: Value for this customer in the open bill run
          readOnly: true
          example: 100
        previousBillRunValue:
          type: number
          description: Value for this customer in the previous bill run
          readOnly: true
          example: 60
        valueDifference:
          type: number
          description: >-
            The difference in monetary value between the previous and the open
            bill run value
          readOnly: true
          example: 40
        percentageDifference:
          type: number
          description: >-
            The difference between the previous and the open bill run value as a
            percentage
          readOnly: true
          example: 80
    CustomerUsageData:
      type: object
      properties:
        id:
          description: Customer usage identifier
          type: integer
          readOnly: true
          format: int64
          example: 1
        customerId:
          type: integer
          description: Customer identifier
          format: int64
          example: 0
        siteId:
          type: integer
          description: Site identifier
          format: int64
          example: 0
        billRunId:
          type: integer
          description: Bill run identifier
          format: int64
          example: 0
        eventDate:
          readOnly: true
          type: string
          description: Event date/time
          format: date-time
        productReference:
          type: string
          description: Product Reference identifier
          format: int64
          example: 0
        serviceId:
          type: string
          description: Service ID
          minLength: 4
          maxLength: 100
          pattern: ^$|[a-zA-Z0-9\p{L}\s()@&.,-_Â£|]{4,100}
        destination:
          type: string
          description: Destination
          maxLength: 100
          minLength: 4
        chargeGroupId:
          type: integer
          description: Charge group identifier
          format: int64
          example: 1
        callClass:
          type: string
          description: Call class
          maxLength: 255
          minLength: 4
        oneOffQuantity:
          type: integer
          description: One-off quantity
          format: int32
        dataQuantity:
          type: number
          description: Data (MB) quantity
        durationQuantity:
          type: integer
          description: Duration (seconds)
          format: int32
        sellPrice:
          type: number
          description: Sell Price
        preDiscountedSellPrice:
          type: number
          description: Pre-discounted sell price
        buyPrice:
          type: number
          description: Buy Price
        ratedBuyPrice:
          type: number
          description: Rated buy Price
        profit:
          type: number
          description: Profit
        profitPercentage:
          type: number
          description: Profit percentage
        marginPercentage:
          type: number
          description: Margin percentage
        timeBand:
          $ref: '#/components/schemas/TimeBand'
        usageProductId:
          type: integer
          description: Usage product identifier
          format: int64
          example: 1
        usageDirection:
          $ref: '#/components/schemas/UsageDirection'
        isdn:
          type: boolean
          description: Is ISDN?
          default: false
        additionalInfoGeneral:
          type: string
          description: Additional info general
        additionalInfoElectronic:
          type: string
          description: Additional info electronic summary
        supplierAccountId:
          description: Supplier account identifier
          type: integer
          format: int64
          example: 1
        fileName:
          type: string
          description: File name
          maxLength: 255
          minLength: 4
        loadedDate:
          type: string
          description: Loaded date/time
          format: date
        parserName:
          type: string
          description: Parser name
          maxLength: 255
          minLength: 4
        fileType:
          type: string
          description: File type
          maxLength: 50
          minLength: 4
    CustomerBillingStatus:
      type: string
      description: Billing status of a customer
      enum:
        - ACTIVE
        - FIRST_INVOICE
        - CEASED
        - RESURRECTED
        - NEVER_BILLED
    CustomerRatingStatus:
      type: string
      description: >-
        Rating status of customer bill runs. If INCOMPLETE, then the bill run
        values are subject to change based on re-rating
      enum:
        - COMPLETE
        - INCOMPLETE
    CustomerType:
      description: Customer type
      type: string
      enum:
        - RESIDENTIAL
        - BUSINESS
        - RESELLER
        - STAFF_MEMBER
    ContactRole:
      description: Contact Role
      type: string
      enum:
        - ACCOUNTS
        - TECHNICAL
        - SALES
        - GENERAL
    ReceiveInvoiceBy:
      description: >-
        Receive invoice by email, post or both? Required when
        contactNameToAppearOnInvoice is set to true
      type: string
      enum:
        - EMAIL
        - POST
        - EMAIL_AND_POST
    ReceiveInvoiceSummaryBy:
      description: Receive invoice summary by email, post or both?
      type: string
      enum:
        - EMAIL
        - POST
        - EMAIL_AND_POST
    TimeBand:
      description: Time band
      type: string
      enum:
        - OFFPEAK
        - PEAK
        - WEEKEND
    UsageDirection:
      description: Usage direction
      type: string
      enum:
        - OUTBOUND
        - INBOUND
    EmailAddress:
      description: Email address
      type: string
      maxLength: 255
      pattern: >-
        (?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-zA-Z0-9-](?:[a-zA-Z0-9-]*[a-zA-Z0-9-])?\.)+[a-zA-Z0-9-](?:[a-zA-Z0-9-]*[a-zA-Z0-9-])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-zA-Z0-9-]*[a-zA-Z0-9-]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
    PageParam:
      description: Page of results to show
      minimum: 1
      type: integer
      format: int32
      example: 1
    ResultsPerPageParam:
      description: Results to return per page
      maximum: 1000
      minimum: 1
      type: integer
      format: int32
      example: 100
    SortParam:
      description: >-
        Comma-delimited list of the fields to sort by - defaults to ascending
        order, suffix :desc to change
      example: id,name | name:desc
      type: string
    FieldsParam:
      description: >-
        Comma-delimited list of the field(s) to return if only a subset is
        required
      example: id,name
      type: string
    IdFilterParam:
      description: Filter by this numeric id value
      example: '0'
      type: string
    StringFilterParam:
      description: >-
        Filter by this string value where value can optionally be prefixed
        (in:|like:)
      example: xyz | in:x,y | like:xyz
      type: string
    DateFilterParam:
      description: >-
        Filter by this date value where value can optionally be prefixed
        (gt:|lt:|gtn:|gen:)
      example: yyyy-MM-dd | lt:yyyy-MM-dd | gt:yyyy-MM-dd | gtn:yyyy-MM-dd
      type: string
    DateTimeFilterParam:
      description: >-
        Filter by this date/time value where value can optionally be prefixed
        (gt:|lt:)
      example: yyyy-MM-ddTHH:mm:ssZ | lt:yyyy-MM-ddTHH:mm:ssZ | gt:yyyy-MM-ddTHH:mm:ssZ
      type: string
    CountryCode:
      description: ISO 3166 alpha-2 code representing country
      type: string
      minLength: 2
      maxLength: 2
      pattern: '[A-Z]{2}'
      example: GB
    Address:
      required:
        - address1
        - town
        - postcode
        - country
      type: object
      properties:
        id:
          type: integer
          description: Internal identifier for address entry
          readOnly: true
          format: int64
          x-si-validation: '@ValidId'
          example: 1
        businessName:
          type: string
          description: Business name
          minLength: 0
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        address1:
          type: string
          description: Address line 1
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        address2:
          type: string
          description: Address line 2
          minLength: 0
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        address3:
          type: string
          description: Address line 3
          minLength: 0
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        town:
          type: string
          description: Town
          minLength: 1
          maxLength: 50
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        county:
          type: string
          description: County
          minLength: 0
          maxLength: 30
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
        postcode:
          type: string
          description: Postcode
          minLength: 0
          maxLength: 20
          pattern: '[a-zA-Z0-9\p{L}@.\-\+_\s]+'
        country:
          $ref: '#/components/schemas/CountryCode'
    PaymentMethod:
      description: Payment method
      type: string
      enum:
        - CHEQUE
        - DIRECT_DEBIT
        - CANCELLED_DD
        - CANCELLED_CARD
        - CREDIT_CARD
        - PAYPAL
        - BACS
        - POST_OFFICE_PAYMENT_CARD
        - EZYPAY
        - GO_CARDLESS
        - GC_INSTANT_BANK_PAYMENTS
        - STRIPE
        - STRIPE_CARD
        - STRIPE_DD
        - FINASTRA
        - FAST_PAY
        - OTHER
    AssignedCustomField:
      required:
        - customFieldDefinitionId
      type: object
      properties:
        id:
          type: integer
          format: int64
          readOnly: true
          example: 1
          description: Unique identifier of the assigned custom field
        customFieldDefinitionId:
          type: integer
          format: int64
          description: Unique identifier of the custom field definition
          example: 1
        label:
          type: string
          description: Display label of the custom field definition
          readOnly: true
          example: Additional field definition label
        value:
          type: string
          minLength: 1
          maxLength: 100
          pattern: '[\w\p{L}\s%£@&#='':;`’,|!_—–\(\)\\/\-\+\.\?\*\$]*'
          description: Value assigned to the assigned custom field (can be null if not set)
          example: Additional field value
    IdParam:
      description: Identifier
      minimum: 1
      type: integer
      format: int64
      example: 1
    BooleanFilterParam:
      description: Filter by this boolean value (true or false)
      example: true | false
      type: string
    PatchDocument:
      description: A JSONPatch document as defined by RFC 6902
      required:
        - op
        - path
      type: object
      properties:
        op:
          type: string
          description: The JSON Patch operation to be performed
          x-si-exclude: true
          enum:
            - add
            - remove
            - replace
            - move
            - copy
            - test
        path:
          type: string
          description: A JSON-Pointer
        value:
          type: object
          properties: {}
          description: The value to be used within the operations
        from:
          type: string
          description: A string containing a JSON Pointer value
    PatchRequest:
      type: array
      description: >-
        JSON Patch is a format for describing changes to a JSON document as
        specified in RFC 6902. Refer to [jsonpatch.com](http://jsonpatch.com/)
        for more information
      items:
        $ref: '#/components/schemas/PatchDocument'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  parameters:
    page:
      name: page
      in: query
      description: Page of results to show
      schema:
        $ref: '#/components/schemas/PageParam'
      required: true
    pageSize:
      name: pageSize
      description: Results to return per page
      in: query
      schema:
        $ref: '#/components/schemas/ResultsPerPageParam'
      required: true
    sort:
      name: sort
      in: query
      description: >-
        Comma-delimited list of the fields to sort by - defaults to ascending
        order, suffix :desc to change
      schema:
        $ref: '#/components/schemas/SortParam'
      required: false
    fields:
      name: fields
      in: query
      description: >-
        Comma-delimited list of the field(s) to return if only a subset is
        required
      schema:
        $ref: '#/components/schemas/FieldsParam'
      required: false
