basePath: /api/v4
definitions:
  handlers.AddContactItemsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.AdjustProjectDatesPayload:
    properties:
      days:
        example: 5
        type: integer
      direction:
        enum:
        - forward
        - backward
        example: forward
        type: string
      shiftchilddates:
        example: 5
        type: integer
    type: object
  handlers.BulkAdjustPhaseDatesPayload:
    properties:
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      shiftchilddates:
        example: 7
        type: integer
    type: object
  handlers.BulkAdjustProjectDatesPayload:
    properties:
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      shiftchilddates:
        example: 7
        type: integer
      shiftdates:
        example: 7
        type: integer
    type: object
  handlers.BulkDeleteInvoicesPayload:
    properties:
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.BulkDeleteProjectsPayload:
    properties:
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.BulkDeleteQuotesPayload:
    properties:
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.BulkUpdateItemWorkStageRequest:
    properties:
      activeworkstageid:
        example: 9
        type: integer
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.BulkUpdateItemsDiscountPayload:
    properties:
      amount:
        example: 100
        type: number
      percent:
        example: 10
        type: number
    type: object
  handlers.BulkUpdateItemsPayload:
    properties:
      billType:
        example: 1
        type: integer
      budgetType:
        description: Financial
        example: 1
        type: integer
      categoryid:
        example: 1
        type: integer
      code:
        example: TASK-001
        type: string
      discount:
        $ref: '#/definitions/handlers.BulkUpdateItemsDiscountPayload'
      duedate:
        example: "2024-02-15"
        type: string
      effortScore:
        example: 2
        type: integer
      hourlyrateserviceid:
        example: 1
        type: integer
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      impactScore:
        example: 3
        type: integer
      importanceScore:
        example: 4
        type: integer
      inAccountingCodeId:
        example: 1
        type: integer
      inLabourPrice:
        example: 40
        type: number
      inTaxCodeId:
        example: 1
        type: integer
      inUnitId:
        example: 1
        type: integer
      inUnitPrice:
        example: 50
        type: number
      inUnitQty:
        example: 10.5
        type: number
      itemtypeid:
        example: 1
        type: integer
      manualBillAmount:
        example: 5000
        type: number
      manualBudget:
        example: 5000
        type: number
      manualPercentageComplete:
        description: Scheduling
        example: 75.5
        type: number
      outAccountingCodeId:
        example: 1
        type: integer
      outLabourPrice:
        example: 60
        type: number
      outLabourPriceMultiplier:
        example: 1.5
        type: number
      outTaxCodeId:
        example: 1
        type: integer
      outUnitId:
        example: 1
        type: integer
      outUnitPrice:
        example: 75
        type: number
      outUnitPriceMultiplier:
        example: 1.5
        type: number
      outUnitQty:
        example: 10.5
        type: number
      priorityid:
        description: Priority
        example: 3
        type: integer
      productid:
        description: Identification
        example: 4
        type: integer
      projectedTimeManual:
        example: 7200
        type: integer
      projectedTimeSpent:
        example: 3600
        type: integer
      shiftDates:
        example: 7
        type: integer
      startdate:
        description: Dates
        example: "2024-01-15"
        type: string
      storyPoints:
        description: Scoring
        example: 5
        type: integer
      urgencyScore:
        example: 3
        type: integer
    type: object
  handlers.BulkUpdatePhasesPayload:
    properties:
      billType:
        example: 1
        type: integer
      budgetType:
        description: Financial
        example: 1
        type: integer
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      inAccountingCodeId:
        example: 1
        type: integer
      inTaxCodeId:
        example: 1
        type: integer
      manualBillAmount:
        example: 5000
        type: number
      manualBudget:
        example: 5000
        type: number
      outAccountingCodeId:
        example: 1
        type: integer
      outTaxCodeId:
        example: 1
        type: integer
    type: object
  handlers.BulkUpdateProjectsPayload:
    properties:
      categoryid:
        description: Classification
        example: 1
        type: integer
      duedate:
        example: "2024-02-15"
        type: string
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      notification:
        description: Settings
        example: true
        type: boolean
      priorityid:
        description: Priority
        example: 3
        type: integer
      startdate:
        description: Dates
        example: "2024-01-15"
        type: string
    type: object
  handlers.BulkUpdateQuotesPayload:
    properties:
      clientaccess:
        description: Access
        example: true
        type: boolean
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      layoutid:
        description: Layout
        example: 5
        type: integer
      validdate:
        description: Dates
        example: "2024-03-31"
        type: string
    type: object
  handlers.CloneDateSetting:
    properties:
      keep:
        example: true
        type: boolean
      newStartDate:
        example: "2026-05-01"
        type: string
    type: object
  handlers.CloneItemsRequest:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      intoCollectionId:
        example: 456
        type: integer
    type: object
  handlers.CloneProjectClientInput:
    properties:
      companyid:
        example: 42
        type: integer
      contactid:
        example: 7
        type: integer
    type: object
  handlers.CloneProjectData:
    properties:
      id:
        example: 123
        type: integer
      number:
        example: PRJ-042
        type: string
      title:
        example: Cloned Project
        type: string
    type: object
  handlers.CloneProjectNexusRequest:
    properties:
      dateSetting:
        $ref: '#/definitions/handlers.CloneDateSetting'
      includeItems:
        example: true
        type: boolean
      includeTags:
        example: true
        type: boolean
      makeTemplate:
        example: false
        type: boolean
      number:
        example: PRJ-042
        type: string
      projectclient:
        $ref: '#/definitions/handlers.CloneProjectClientInput'
      title:
        example: Cloned Project
        type: string
    type: object
  handlers.CloneProjectNexusResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.CloneProjectData'
      message:
        example: Project cloned
        type: string
      status:
        example: success
        type: string
    type: object
  handlers.CloneQuoteInvoiceRequest:
    properties:
      companyid:
        example: 42
        type: integer
      makeTemplate:
        example: false
        type: boolean
      title:
        example: Cloned Invoice
        type: string
    type: object
  handlers.CompanyContactCreatePayload:
    properties:
      companyid:
        type: integer
    type: object
  handlers.CompanyContactItem:
    properties:
      email:
        example: jane@example.com
        type: string
      firstname:
        example: Jane
        type: string
      id:
        example: 42
        type: integer
      image:
        example: https://example.com/avatar.jpg
        type: string
      lastname:
        example: Smith
        type: string
      mobilephone:
        example: +1 555 0101
        type: string
      name:
        example: Jane Smith
        type: string
      type:
        example: staff
        type: string
      workphone:
        example: +1 555 0100
        type: string
    type: object
  handlers.CompanyGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.CompanyResponse'
      status:
        example: success
        type: string
    type: object
  handlers.CompanyListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.CompanyResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.CompanyLocationCreatePayload:
    properties:
      active:
        example: true
        type: boolean
      addressLine1:
        example: 123 Main St
        type: string
      addressLine2:
        example: Suite 100
        type: string
      addressLine3:
        example: ""
        type: string
      city:
        example: New York
        type: string
      code:
        example: HQ
        type: string
      companyid:
        example: 1
        type: integer
      countryid:
        example: 1
        type: integer
      deliveryInstructions:
        example: Leave at reception
        type: string
      description:
        example: Primary office location
        type: string
      email:
        example: office@example.com
        type: string
      formattedAddress:
        example: 123 Main St, New York, NY 10001
        type: string
      latitude:
        example: -36.8485
        type: number
      longitude:
        example: 174.7633
        type: number
      name:
        example: Head Office
        type: string
      phone:
        example: +1 555 0100
        type: string
      phone2:
        example: +1 555 0101
        type: string
      placeid:
        example: ChIJN1t_tDeuEmsRUsoyG83frY4
        type: string
      stateRegion:
        example: NY
        type: string
      suburb:
        example: Downtown
        type: string
      type:
        example: postal
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.CompanyLocationGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.CompanyLocationResponse'
      status:
        example: success
        type: string
    type: object
  handlers.CompanyLocationItem:
    properties:
      active:
        type: boolean
      address1:
        type: string
      address2:
        type: string
      address3:
        type: string
      city:
        type: string
      code:
        type: string
      companyid:
        type: integer
      countryid:
        type: integer
      deliveryinstructions:
        type: string
      email:
        type: string
      formattedaddress:
        type: string
      id:
        type: integer
      lastmodifiedutc:
        type: string
      latitude:
        type: number
      longitude:
        type: number
      name:
        type: string
      phone:
        type: string
      phone2:
        type: string
      placeid:
        type: string
      state:
        type: string
      suburb:
        type: string
      zipcode:
        type: string
    type: object
  handlers.CompanyLocationListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.CompanyLocationResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.CompanyLocationResponse:
    properties:
      active:
        type: boolean
      address1:
        type: string
      address2:
        type: string
      address3:
        type: string
      city:
        type: string
      code:
        type: string
      companyid:
        type: integer
      countryid:
        type: integer
      deliveryinstructions:
        type: string
      email:
        type: string
      formattedaddress:
        type: string
      id:
        type: integer
      lastmodifiedutc:
        type: string
      latitude:
        type: number
      longitude:
        type: number
      name:
        type: string
      phone:
        type: string
      phone2:
        type: string
      placeid:
        type: string
      state:
        type: string
      suburb:
        type: string
      zipcode:
        type: string
    type: object
  handlers.CompanyLocationUpdatePayload:
    properties:
      active:
        example: true
        type: boolean
      addressLine1:
        example: 123 Main St
        type: string
      addressLine2:
        example: Suite 100
        type: string
      addressLine3:
        example: ""
        type: string
      city:
        example: New York
        type: string
      code:
        example: HQ
        type: string
      countryid:
        example: 1
        type: integer
      deliveryInstructions:
        example: Leave at reception
        type: string
      description:
        example: Primary office location
        type: string
      email:
        example: office@example.com
        type: string
      formattedAddress:
        example: 123 Main St, New York, NY 10001
        type: string
      latitude:
        example: -36.8485
        type: number
      longitude:
        example: 174.7633
        type: number
      name:
        example: Head Office
        type: string
      phone:
        example: +1 555 0100
        type: string
      phone2:
        example: +1 555 0101
        type: string
      placeid:
        example: ChIJN1t_tDeuEmsRUsoyG83frY4
        type: string
      stateRegion:
        example: NY
        type: string
      suburb:
        example: Downtown
        type: string
      type:
        example: postal
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.CompanyNoteCreatePayload:
    properties:
      companyid:
        example: 1
        type: integer
      note:
        example: Follow up scheduled for next week.
        type: string
    type: object
  handlers.CompanyNoteGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.CompanyNoteResponse'
      status:
        example: success
        type: string
    type: object
  handlers.CompanyNoteListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.CompanyNoteResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.CompanyNoteResponse:
    properties:
      companyid:
        type: integer
      creatorid:
        type: integer
      creatorname:
        type: string
      datecreated:
        type: string
      id:
        type: integer
      lastmodifiedutc:
        type: string
      note:
        type: string
    type: object
  handlers.CompanyNoteUpdatePayload:
    properties:
      note:
        example: Updated follow up note.
        type: string
    type: object
  handlers.CompanyProjectCreatePayload:
    properties:
      number:
        example: PRJ-001
        type: string
      title:
        example: Website Redesign
        type: string
    type: object
  handlers.CompanyResponse:
    properties:
      code:
        type: string
      contacts:
        items:
          $ref: '#/definitions/handlers.CompanyContactItem'
        type: array
      email:
        type: string
      fax:
        type: string
      id:
        type: integer
      image:
        type: string
      lastmodifiedutc:
        type: string
      locations:
        items:
          $ref: '#/definitions/handlers.CompanyLocationItem'
        type: array
      maincompanylocationid:
        type: integer
      name:
        type: string
      phone:
        type: string
      tags:
        items:
          $ref: '#/definitions/handlers.CompanyTagItem'
        type: array
      type:
        type: string
      website:
        type: string
    type: object
  handlers.CompanySummaryContactItem:
    properties:
      companyid:
        example: 42
        type: integer
      companyname:
        example: Acme Corp
        type: string
      email:
        example: john@example.com
        type: string
      id:
        example: 1
        type: integer
      mobilephone:
        example: 555-5678
        type: string
      name:
        example: John Smith
        type: string
      type:
        example: client
        type: string
      workphone:
        example: 555-1234
        type: string
    type: object
  handlers.CompanySummaryData:
    properties:
      contacts:
        items:
          $ref: '#/definitions/handlers.CompanySummaryContactItem'
        type: array
      invoices:
        items:
          $ref: '#/definitions/handlers.CompanySummaryInvoiceItem'
        type: array
      phases:
        items:
          $ref: '#/definitions/handlers.CompanySummaryPhaseItem'
        type: array
      projects:
        items:
          $ref: '#/definitions/handlers.CompanySummaryProjectItem'
        type: array
      quotes:
        items:
          $ref: '#/definitions/handlers.CompanySummaryQuoteItem'
        type: array
      totals:
        $ref: '#/definitions/handlers.CompanySummaryTotals'
    type: object
  handlers.CompanySummaryInvoiceItem:
    properties:
      companyid:
        example: 42
        type: integer
      companyname:
        example: Acme Corp
        type: string
      grandtotal:
        example: 1100
        type: number
      id:
        example: 1
        type: integer
      number:
        example: INV-001
        type: string
      subtotal:
        example: 1000
        type: number
      taxtotal:
        example: 100
        type: number
      title:
        example: Website Redesign
        type: string
    type: object
  handlers.CompanySummaryPhaseItem:
    properties:
      id:
        example: 1
        type: integer
      name:
        example: Design Phase
        type: string
      projectid:
        example: 10
        type: integer
      projectnumber:
        example: PRJ-001
        type: string
      projecttitle:
        example: Website Redesign
        type: string
    type: object
  handlers.CompanySummaryProjectItem:
    properties:
      companyid:
        example: 42
        type: integer
      companyname:
        example: Acme Corp
        type: string
      id:
        example: 1
        type: integer
      number:
        example: PRJ-001
        type: string
      title:
        example: Website Redesign
        type: string
    type: object
  handlers.CompanySummaryQuoteItem:
    properties:
      companyid:
        example: 42
        type: integer
      companyname:
        example: Acme Corp
        type: string
      grandtotal:
        example: 1100
        type: number
      id:
        example: 1
        type: integer
      number:
        example: Q-001
        type: string
      subtotal:
        example: 1000
        type: number
      taxtotal:
        example: 100
        type: number
      title:
        example: Website Redesign
        type: string
    type: object
  handlers.CompanySummaryResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.CompanySummaryData'
      status:
        example: success
        type: string
    type: object
  handlers.CompanySummaryTotals:
    properties:
      contacts:
        example: 42
        type: integer
      invoices:
        example: 10
        type: integer
      phases:
        example: 8
        type: integer
      projects:
        example: 5
        type: integer
      quotes:
        example: 3
        type: integer
    type: object
  handlers.CompanyTagItem:
    properties:
      color:
        example: '#FF0000'
        type: string
      id:
        example: 1
        type: integer
      name:
        example: VIP
        type: string
    type: object
  handlers.CompanyTagListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.CompanyTagResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.CompanyTagResponse:
    properties:
      color:
        example: A4C0DE
        type: string
      id:
        example: 1
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: VIP
        type: string
      sortorder:
        example: 1
        type: integer
    type: object
  handlers.CompanyTagUpdatePayload:
    properties:
      tagid:
        items:
          type: integer
        type: array
    type: object
  handlers.CompleteItemsRequest:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.ContactDetailResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ContactResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactGroupGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ContactGroupResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactGroupListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ContactGroupResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactGroupResponse:
    properties:
      contactid:
        items:
          type: integer
        type: array
      id:
        type: integer
      name:
        type: string
      teamid:
        type: integer
    type: object
  handlers.ContactGroupsResponse:
    properties:
      groups:
        items:
          $ref: '#/definitions/handlers.GroupTeamItem'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
      teams:
        items:
          $ref: '#/definitions/handlers.GroupTeamItem'
        type: array
    type: object
  handlers.ContactListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ContactResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactNoteGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ContactNoteResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactNoteListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ContactNoteResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactNoteResponse:
    properties:
      authorid:
        type: integer
      authorname:
        type: string
      content:
        type: string
      date:
        type: string
      id:
        type: integer
    type: object
  handlers.ContactPermissionResponse:
    properties:
      add:
        example: true
        type: boolean
      contactid:
        example: 5
        type: integer
      delete:
        example: false
        type: boolean
      edit:
        example: true
        type: boolean
      name:
        example: Manage Companies
        type: string
      permissionid:
        example: 8
        type: integer
      view:
        example: true
        type: boolean
    type: object
  handlers.ContactProjectsPayload:
    properties:
      projectid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.ContactResponse:
    properties:
      address1:
        example: 123 Main St
        type: string
      address2:
        example: Suite 100
        type: string
      address3:
        example: ""
        type: string
      allowlogin:
        example: true
        type: boolean
      city:
        example: New York
        type: string
      companyid:
        example: 1
        type: integer
      companyname:
        example: Acme Corp
        type: string
      country:
        example: USA
        type: string
      defaulthourlyrateid:
        example: 1
        type: integer
      divisionid:
        example: 1
        type: integer
      email:
        example: john@example.com
        type: string
      fax:
        example: 123-456-7892
        type: string
      firstname:
        example: John
        type: string
      groups:
        items:
          $ref: '#/definitions/handlers.ContactSubGroup'
        type: array
      ianatimezone:
        example: Pacific/Auckland
        type: string
      id:
        example: 1
        type: integer
      image:
        example: https://cdn.proworkflow.com/images/contact/1.jpg
        type: string
      lastmodifiedutc:
        example: 2024-01-15T15:30:00
        type: string
      lastname:
        example: Smith
        type: string
      mobilephone:
        example: 123-456-7891
        type: string
      notes:
        items:
          $ref: '#/definitions/handlers.ContactSubNote'
        type: array
      payrate:
        example: 50
        type: number
      payratemultiplier:
        example: 1.5
        type: number
      pending:
        example: false
        type: boolean
      roles:
        items:
          $ref: '#/definitions/handlers.ContactSubRole'
        type: array
      state:
        example: NY
        type: string
      status:
        example: active
        type: string
      tags:
        items:
          $ref: '#/definitions/handlers.ContactSubTag'
        type: array
      teams:
        items:
          $ref: '#/definitions/handlers.ContactSubTeam'
        type: array
      title:
        example: CEO
        type: string
      type:
        example: staff
        type: string
      username:
        example: jsmith
        type: string
      workphone:
        example: 123-456-7890
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.ContactRoleListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ContactRoleResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactRoleResponse:
    properties:
      displayorder:
        example: 1
        type: integer
      id:
        example: 1
        type: integer
      name:
        example: Developer
        type: string
    type: object
  handlers.ContactRolesPayload:
    properties:
      roleid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.ContactSubGroup:
    properties:
      id:
        example: 1
        type: integer
      name:
        example: Designers
        type: string
    type: object
  handlers.ContactSubNote:
    properties:
      authorid:
        example: 10
        type: integer
      authorname:
        example: John Smith
        type: string
      content:
        example: This is a note about the contact
        type: string
      date:
        example: 2024-01-18T13:20:00
        type: string
      id:
        example: 1
        type: integer
    type: object
  handlers.ContactSubRole:
    properties:
      color:
        example: A4C0DE
        type: string
      id:
        example: 1
        type: integer
      name:
        example: Manager
        type: string
    type: object
  handlers.ContactSubTag:
    properties:
      color:
        example: A4C0DE
        type: string
      id:
        example: 1
        type: integer
      name:
        example: VIP
        type: string
    type: object
  handlers.ContactSubTeam:
    properties:
      id:
        example: 1
        type: integer
      name:
        example: Marketing
        type: string
    type: object
  handlers.ContactTagGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ContactTagResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactTagListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ContactTagResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ContactTagResponse:
    properties:
      color:
        example: A4C0DE
        type: string
      id:
        example: 1
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: VIP
        type: string
    type: object
  handlers.ContactsToItemsPayload:
    properties:
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.CreateCompanyPayload:
    properties:
      avatarname:
        example: avatar.jpg
        type: string
      categoryid:
        description: Additional fields
        example: 1
        type: integer
      code:
        example: ABC
        type: string
      companies:
        description: Batch creation (array of companies)
        items:
          $ref: '#/definitions/handlers.CreateCompanyPayload'
        type: array
      creatorid:
        example: 1
        type: integer
      email:
        example: info@abc.com
        type: string
      facebook:
        description: Social media
        example: https://facebook.com/abc
        type: string
      fax:
        example: 123-456-7891
        type: string
      isperson:
        type: boolean
      linkedin:
        example: https://linkedin.com/company/abc
        type: string
      maincompanylocationid:
        example: 1
        type: integer
      maincontactid:
        example: 1
        type: integer
      name:
        description: Basic fields
        example: ABC Corporation
        type: string
      phone:
        description: Contact information
        example: 123-456-7890
        type: string
      tagid:
        description: Tags
        example: 1,2,3
        type: string
      twitter:
        example: '@abccorp'
        type: string
      type:
        enum:
        - client
        - contractor
        - staff
        - other
        example: client
        type: string
      website:
        example: https://www.abc.com
        type: string
    type: object
  handlers.CreateContactNotePayload:
    properties:
      note:
        example: This is a note about the contact
        type: string
    type: object
  handlers.CreateContactPayload:
    properties:
      address1:
        description: Address
        example: 123 Main St
        type: string
      address2:
        example: Suite 100
        type: string
      address3:
        example: ""
        type: string
      allowlogin:
        description: Login/Access
        example: true
        type: boolean
      city:
        example: New York
        type: string
      companyid:
        description: Company/Organization
        example: 1
        type: integer
      country:
        example: USA
        type: string
      defaulthourlyrateid:
        description: Additional
        example: 1
        type: integer
      divisionid:
        example: 1
        type: integer
      email:
        example: john@example.com
        type: string
      emailsignature:
        description: Settings
        example: <p>Best regards,<br>John</p>
        type: string
      firstname:
        description: Basic information
        example: John
        type: string
      groupid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      ianatimezone:
        example: Pacific/Auckland
        type: string
      lastname:
        example: Smith
        type: string
      mobilephone:
        example: 123-456-7891
        type: string
      primarycontact:
        type: boolean
      roleid:
        example: 1,2
        type: string
      showhistoric:
        type: boolean
      state:
        example: NY
        type: string
      tagid:
        description: Tags
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      title:
        example: CEO
        type: string
      type:
        enum:
        - client
        - contractor
        - staff
        - other
        - supplier
        example: client
        type: string
      workphone:
        description: Contact information
        example: 123-456-7890
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.CreateContactTagPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: VIP
        type: string
    type: object
  handlers.CreateCustomFieldOptionPayload:
    properties:
      customfieldid:
        type: integer
      deleted:
        type: boolean
      name:
        type: string
    type: object
  handlers.CreateCustomFieldPayload:
    properties:
      active:
        type: boolean
      name:
        type: string
      staffonly:
        type: boolean
      type:
        enum:
        - checkbox
        - date
        - dropdown
        - number
        - percentage
        - rating
        - staff
        - text
        type: string
    type: object
  handlers.CreateExternalProjectPayload:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      categoryid:
        description: Categorization
        example: 1
        type: integer
      chargeRateType:
        example: 1
        type: integer
      clientaccess:
        description: Access settings
        type: boolean
      clientid:
        description: Additional contact assignments
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      clientviewalltasks:
        type: boolean
      companyid:
        description: External client (required)
        example: 5
        type: integer
      completedate:
        example: "2024-04-01"
        type: string
      contractorid:
        example:
        - 4
        - 5
        items:
          type: integer
        type: array
      costRateType:
        description: Financial fields
        example: 1
        type: integer
      customfields:
        description: Custom field values to set on creation
        items:
          $ref: '#/definitions/handlers.ProjectCustomFieldInput'
        type: array
      customformtitle:
        example: Custom Form
        type: string
      description:
        example: Complete website redesign project
        type: string
      divisionid:
        description: Division/Organization
        example: 1
        type: integer
      duedate:
        example: "2024-03-15"
        type: string
      icalcontactid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      managementteam:
        allOf:
        - $ref: '#/definitions/handlers.ProjectManagementTeam'
        description: Management team (required)
      notification:
        type: boolean
      number:
        example: PRJ-001
        type: string
      priorityid:
        example: 2
        type: integer
      privatenotes:
        description: Additional fields
        example: Internal notes
        type: string
      purchaseorder:
        example: PO-12345
        type: string
      staffid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      staffviewalltasks:
        type: boolean
      startdate:
        description: Date fields
        example: "2024-01-15"
        type: string
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      template:
        type: boolean
      templateused:
        example: 1
        type: integer
      timeallocated:
        example: 3600
        type: integer
      title:
        description: Basic fields
        example: Website Redesign
        type: string
      worktypeid:
        example: 1
        type: integer
    type: object
  handlers.CreateFolderPayload:
    properties:
      contactid:
        items:
          type: integer
        type: array
      description:
        example: Assets for client review
        type: string
      name:
        example: Client Assets
        type: string
      ownerid:
        example: 2
        type: integer
      projectid:
        example: 10
        type: integer
      public:
        example: false
        type: boolean
      size:
        example: 204800
        type: integer
      taskid:
        example: 5
        type: integer
      type:
        example: custom
        type: string
    type: object
  handlers.CreateGroupPayload:
    properties:
      contactids:
        example: 1,2,3
        type: string
      name:
        example: Design Team
        type: string
      sortorder:
        example: "1"
        type: string
      teamid:
        example: 1
        type: integer
    type: object
  handlers.CreateInternalProjectPayload:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      categoryid:
        description: Categorization
        example: 1
        type: integer
      chargeRateType:
        example: 1
        type: integer
      clientaccess:
        description: Access settings
        type: boolean
      clientviewalltasks:
        type: boolean
      completedate:
        example: "2024-04-01"
        type: string
      contactid:
        description: Internal client (required)
        example: 101
        type: integer
      contractorid:
        description: Additional contact assignments
        example:
        - 4
        - 5
        items:
          type: integer
        type: array
      costRateType:
        description: Financial fields
        example: 1
        type: integer
      customfields:
        description: Custom field values to set on creation
        items:
          $ref: '#/definitions/handlers.ProjectCustomFieldInput'
        type: array
      customformtitle:
        example: Custom Form
        type: string
      description:
        example: Internal finance process improvement
        type: string
      divisionid:
        description: Division/Organization
        example: 1
        type: integer
      duedate:
        example: "2024-03-15"
        type: string
      groupid:
        example: 1
        type: integer
      icalcontactid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      managementteam:
        allOf:
        - $ref: '#/definitions/handlers.ProjectManagementTeam'
        description: Management team (required)
      notification:
        type: boolean
      number:
        example: PRJ-002
        type: string
      priorityid:
        example: 2
        type: integer
      privatenotes:
        description: Additional fields
        example: Internal notes
        type: string
      purchaseorder:
        example: PO-12345
        type: string
      staffid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      staffviewalltasks:
        type: boolean
      startdate:
        description: Date fields
        example: "2024-01-15"
        type: string
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      teamid:
        example: 1
        type: integer
      template:
        type: boolean
      templateused:
        example: 1
        type: integer
      timeallocated:
        example: 3600
        type: integer
      title:
        description: Basic fields
        example: Finance Process Review
        type: string
      worktypeid:
        example: 1
        type: integer
    type: object
  handlers.CreateInvoiceFromProjectPayload:
    properties:
      companyid:
        example: 123
        type: integer
      duedate:
        example: "2024-02-15"
        type: string
      groupby:
        enum:
        - project
        - phase
        - item
        - staff
        example: project
        type: string
      invoicedate:
        example: "2024-01-15"
        type: string
      invoiceid:
        example: 456
        type: integer
      invoicetermid:
        example: 1
        type: integer
      itemcollectionName:
        example: Time Entries
        type: string
      itemid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      number:
        example: INV-001
        type: string
      timelogid:
        example:
        - 10
        - 11
        - 12
        items:
          type: integer
        type: array
      title:
        example: Website Redesign Invoice
        type: string
    type: object
  handlers.CreateInvoicePayload:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      companyid:
        description: Company/Project
        example: 5
        type: integer
      description:
        example: Invoice for services rendered
        type: string
      duedate:
        example: "2024-02-15"
        type: string
      invoicedate:
        description: Dates
        example: "2024-01-15"
        type: string
      invoicetermid:
        description: Additional fields
        example: 1
        type: integer
      number:
        example: INV-001
        type: string
      projectid:
        example: 10
        type: integer
      purchaseordernumber:
        example: PO-12345
        type: string
      template:
        type: boolean
      title:
        description: Basic fields
        example: New Invoice
        type: string
    type: object
  handlers.CreateInvoicePhasePayload:
    properties:
      billtype:
        example: 1
        type: integer
      budgettype:
        example: 1
        type: integer
      invoiceid:
        example: 123
        type: integer
      name:
        example: Phase 1
        type: string
    type: object
  handlers.CreateItemCategoryPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Design
        type: string
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.CreateItemPayload:
    properties:
      billType:
        example: 1
        type: integer
      budgetType:
        example: 1
        type: integer
      categoryid:
        example: 1
        type: integer
      chargeRateType:
        example: 1
        type: integer
      code:
        example: TASK-001
        type: string
      completedate:
        example: "2024-02-20"
        type: string
      contactid:
        example: 1,2,3
        type: string
      costRateType:
        example: 1
        type: integer
      description:
        example: Design the homepage layout
        type: string
      duedate:
        example: "2024-02-15"
        type: string
      effortScore:
        example: medium
        type: string
      effortScoreId:
        example: 2
        type: integer
      hourlyrateserviceid:
        example: 1
        type: integer
      impactScore:
        example: high
        type: string
      impactScoreId:
        example: 1
        type: integer
      importanceScore:
        example: high
        type: string
      importanceScoreId:
        example: 1
        type: integer
      inAccountingCodeId:
        example: 1
        type: integer
      inLabourPrice:
        example: 40
        type: number
      inTaxCodeId:
        example: 1
        type: integer
      inUnitId:
        example: 1
        type: integer
      inUnitPrice:
        example: 50
        type: number
      inUnitQty:
        example: 10.5
        type: number
      itemcollectionid:
        example: 5
        type: integer
      items:
        items:
          $ref: '#/definitions/handlers.CreateItemPayload'
        type: array
      itemtypeid:
        example: 1
        type: integer
      manualPercentageComplete:
        example: 75.5
        type: number
      name:
        example: Design Homepage
        type: string
      outAccountingCodeId:
        example: 1
        type: integer
      outLabourPrice:
        example: 60
        type: number
      outLabourPriceMultiplier:
        example: 1.5
        type: number
      outTaxCodeId:
        example: 1
        type: integer
      outUnitId:
        example: 1
        type: integer
      outUnitPrice:
        example: 75
        type: number
      outUnitPriceMultiplier:
        example: 1.5
        type: number
      outUnitQty:
        example: 10.5
        type: number
      parentid:
        example: 2
        type: integer
      prerequisiteid:
        example: 1,2,3
        type: string
      priority:
        example: 3
        type: integer
      priorityid:
        example: 3
        type: integer
      productid:
        example: 4
        type: integer
      projectedTimeManual:
        example: 7200
        type: integer
      projectedTimeSpent:
        example: 3600
        type: integer
      startdate:
        example: "2024-01-15"
        type: string
      status:
        enum:
        - active
        - complete
        example: active
        type: string
      storyPoints:
        example: 5
        type: integer
      tagid:
        example: 1,2
        type: string
      trackingOptionId:
        example: 1,2
        type: string
      urgencyScore:
        example: medium
        type: string
      urgencyScoreId:
        example: 2
        type: integer
    type: object
  handlers.CreateItemTagPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Urgent
        type: string
    type: object
  handlers.CreateMessagePayload:
    properties:
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      content:
        example: Here is the latest update...
        type: string
      fileid:
        example: 10,11
        type: string
      itemid:
        example: 5
        type: integer
      projectid:
        example: 10
        type: integer
      public:
        example: false
        type: boolean
      subject:
        example: Project update
        type: string
    type: object
  handlers.CreateProjectBookmarkPayload:
    properties:
      title:
        example: Example Site
        type: string
      url:
        example: https://example.com
        type: string
    type: object
  handlers.CreateProjectCategoryPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Marketing
        type: string
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.CreateProjectItemPayload:
    properties:
      categoryid:
        example: 1
        type: integer
      code:
        example: TASK-001
        type: string
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      description:
        example: Create homepage design mockups
        type: string
      duedate:
        example: "2024-01-20"
        type: string
      itemcollectionid:
        example: 5
        type: integer
      itemtypeid:
        example: 1
        type: integer
      name:
        example: Design homepage
        type: string
      priority:
        example: 2
        type: integer
      startdate:
        example: "2024-01-15"
        type: string
      tagids:
        example: 1,2
        type: string
    type: object
  handlers.CreateProjectMessagePayload:
    properties:
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      content:
        example: The project is progressing well
        type: string
      itemid:
        example: 1
        type: integer
      public:
        example: true
        type: boolean
      subject:
        example: Project Update
        type: string
    type: object
  handlers.CreateProjectPhasePayload:
    properties:
      duedate:
        example: "2024-02-15"
        type: string
      name:
        example: Design Phase
        type: string
      startdate:
        example: "2024-01-15"
        type: string
    type: object
  handlers.CreateProjectTagPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Urgent
        type: string
    type: object
  handlers.CreateQuoteFromProjectPayload:
    properties:
      companyid:
        example: 123
        type: integer
      itemid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      number:
        example: Q-001
        type: string
      quotedate:
        example: "2024-01-15"
        type: string
      quoteid:
        example: 456
        type: integer
      title:
        example: Website Redesign Quote
        type: string
    type: object
  handlers.CreateQuoteItemPayload:
    properties:
      billamount:
        example: 6000
        type: number
      billtype:
        example: 1
        type: integer
      budget:
        example: 5000
        type: number
      budgettype:
        example: 1
        type: integer
      categoryid:
        example: 2
        type: integer
      duedate:
        example: "2024-01-31"
        type: string
      itemcollectionid:
        example: 456
        type: integer
      itemtypeid:
        example: 1
        type: integer
      name:
        example: Design Work
        type: string
      parentid:
        example: 0
        type: integer
      quoteid:
        example: 123
        type: integer
      startdate:
        example: "2024-01-01"
        type: string
      timeallocated:
        example: 40
        type: number
    type: object
  handlers.CreateQuotePayload:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      clientaccess:
        type: boolean
      companyid:
        description: Company/Project
        example: 5
        type: integer
      description:
        example: Quote for services
        type: string
      number:
        example: QUO-001
        type: string
      projectid:
        example: 10
        type: integer
      quotedate:
        description: Dates
        example: "2024-01-15"
        type: string
      quoteperiod:
        example: 30
        type: integer
      template:
        type: boolean
      title:
        description: Basic fields
        example: New Quote
        type: string
      type:
        description: Additional fields
        enum:
        - estimate
        - quote
        example: quote
        type: string
      validdate:
        example: "2024-02-15"
        type: string
    type: object
  handlers.CreateQuotePhasePayload:
    properties:
      billamount:
        example: 6000
        type: number
      billtype:
        example: 1
        type: integer
      budget:
        example: 5000
        type: number
      budgettype:
        example: 1
        type: integer
      duedate:
        example: "2024-01-31"
        type: string
      name:
        example: Phase 1
        type: string
      quoteid:
        example: 123
        type: integer
      startdate:
        example: "2024-01-01"
        type: string
    type: object
  handlers.CreateResthookPayload:
    properties:
      event:
        description: 'Event type. One of: newcontact, newpendingcontact, editcontact,
          editcontactlocation, deletecontact, newcompany, newpendingcompany, editcompany,
          deletecompany, newfile, deletefile, newinvoice, editinvoice, deleteinvoice,
          newmessage, editmessage, deletemessage, newproject, editproject, editstageproject,
          deleteproject, completeproject, restoreProject, newprojectrequest, editprojectrequest,
          deleteprojectrequest, approveprojectrequest, declineprojectrequest, newquote,
          editquote, deletequote, newsharednote, editsharednote, deletesharednote,
          newtask, edittask, deletetask, completetask, reactivatetask, newtime, edittime,
          deletetime, starttimer, stoptimer, unknown'
        enum:
        - newcontact
        - newpendingcontact
        - editcontact
        - editcontactlocation
        - deletecontact
        - newcompany
        - newpendingcompany
        - editcompany
        - deletecompany
        - newfile
        - deletefile
        - newinvoice
        - editinvoice
        - deleteinvoice
        - newmessage
        - editmessage
        - deletemessage
        - newproject
        - editproject
        - editstageproject
        - deleteproject
        - completeproject
        - restoreProject
        - newprojectrequest
        - editprojectrequest
        - deleteprojectrequest
        - approveprojectrequest
        - declineprojectrequest
        - newquote
        - editquote
        - deletequote
        - newsharednote
        - editsharednote
        - deletesharednote
        - newtask
        - edittask
        - deletetask
        - completetask
        - reactivatetask
        - newtime
        - edittime
        - deletetime
        - starttimer
        - stoptimer
        - unknown
        example: newproject
        type: string
      url:
        example: https://example.com/webhook
        type: string
    type: object
  handlers.CreateRolePayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Project Manager
        type: string
      permissions:
        items:
          $ref: '#/definitions/handlers.SetRolePermissionInput'
        type: array
      type:
        enum:
        - client
        - contractor
        - staff
        - other
        example: staff
        type: string
    type: object
  handlers.CreateTeamPayload:
    properties:
      code:
        example: ENG
        type: string
      groupids:
        example: 1,2,3
        type: string
      name:
        example: Engineering
        type: string
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.CreateTemplatePhaseForTemplatePayload:
    properties:
      name:
        example: Design Phase
        type: string
      parentid:
        example: 0
        type: integer
    type: object
  handlers.CustomFieldListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.CustomFieldResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.CustomFieldOptionItem:
    properties:
      displayorder:
        type: integer
      id:
        type: integer
      value:
        type: string
    type: object
  handlers.CustomFieldResponse:
    properties:
      id:
        example: 1
        type: integer
      isActive:
        example: true
        type: boolean
      name:
        example: Priority Level
        type: string
      sortorder:
        example: "1"
        type: string
      staffonly:
        example: false
        type: boolean
      type:
        example: dropdown
        type: string
      values:
        items:
          $ref: '#/definitions/handlers.CustomFieldOptionItem'
        type: array
    type: object
  handlers.DivisionGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.DivisionResponse'
      status:
        example: success
        type: string
    type: object
  handlers.DivisionListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.DivisionResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.DivisionResponse:
    properties:
      chargeRateType:
        example: hourly
        type: string
      costRateType:
        example: hourly
        type: string
      currencyid:
        example: 1
        type: integer
      defaultpayrate:
        example: 50
        type: number
      ianatimezone:
        example: "0"
        type: string
      id:
        example: 1
        type: integer
      name:
        example: Engineering Division
        type: string
      payratemultiplier:
        example: 1.5
        type: number
    type: object
  handlers.FileGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.FileResponse'
      status:
        type: string
    type: object
  handlers.FileListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.FileResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        type: string
    type: object
  handlers.FileResponse:
    properties:
      contactids:
        type: string
      date:
        type: string
      description:
        type: string
      folderid:
        type: integer
      foldername:
        type: string
      id:
        type: integer
      itemid:
        type: integer
      itemname:
        type: string
      link:
        type: string
      name:
        type: string
      ownerid:
        type: integer
      projectid:
        type: integer
      projectnumber:
        type: string
      projecttitle:
        type: string
      size:
        type: integer
    type: object
  handlers.FileUploadData:
    properties:
      fileid:
        example: 123
        type: integer
      filesize:
        example: 5242880
        type: integer
      folderid:
        example: 456
        type: integer
      name:
        example: document.pdf
        type: string
    type: object
  handlers.FileUploadResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.FileUploadData'
      status:
        example: success
        type: string
    type: object
  handlers.FolderGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.FolderResponse'
      status:
        example: success
        type: string
    type: object
  handlers.FolderListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.FolderResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.FolderResponse:
    properties:
      contacts:
        example: 1,2,3
        type: string
      date:
        example: 2024-01-18T13:20:00
        type: string
      description:
        example: Assets for client review
        type: string
      id:
        example: 1
        type: integer
      itemid:
        example: 5
        type: integer
      name:
        example: Client Assets
        type: string
      ownerid:
        example: 2
        type: integer
      projectid:
        example: 10
        type: integer
      projectnumber:
        example: PRJ-001
        type: string
      projecttitle:
        example: Website Redesign
        type: string
      public:
        example: false
        type: boolean
      size:
        example: 204800
        type: integer
      type:
        example: custom
        type: string
    type: object
  handlers.GroupTeamItem:
    properties:
      id:
        example: 1
        type: integer
      name:
        example: Marketing Team
        type: string
    type: object
  handlers.GroupsToContactsPayload:
    properties:
      groupid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.InvoiceGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.InvoiceResponse'
      status:
        example: success
        type: string
    type: object
  handlers.InvoiceItemCreatePayload:
    properties:
      billable:
        type: boolean
      itemcollectionid:
        type: integer
      itemtypeid:
        type: integer
      name:
        example: Homepage Design
        type: string
      parentid:
        type: integer
    type: object
  handlers.InvoiceItemGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.InvoiceItemResponse'
      status:
        example: success
        type: string
    type: object
  handlers.InvoiceItemListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.InvoiceItemResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.InvoiceItemResponse:
    properties:
      activeworkstageid:
        description: Status & scheduling
        type: integer
      activeworkstate:
        type: string
      billAmount:
        description: BillAmount is calculated based on BillType config
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item rates and quantities, 2 = fixed fee, 3 = unit prices,
          4 = item rates, 5 = hours spent and quantities, 8 = hours spent
        type: integer
      billable:
        type: boolean
      budget:
        description: Budget is calculated based on BudgetType config
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals, 3 = unit prices, 4 = item rates'
        type: integer
      categoryid:
        type: integer
      chargeRateType:
        description: |-
          ChargeRateType determines how output costs are calculated:
          1 (Single Rate) = use outLabourPrice; 2 (Split Rate) = use outLabourPrice of linked hourly rate services; 0 = no charge rate tracking
        type: string
      code:
        type: string
      contactid:
        items:
          type: integer
        type: array
      costRateType:
        description: |-
          CostRateType determines how input costs are calculated:
          1 (Staff Rate) = use rate of linked staff members; 2 (Service Rate) = use rate of linked hourly rate services; 0 = no cost rate tracking
        type: string
      createdatetime:
        type: string
      creatorid:
        type: integer
      deleted:
        type: boolean
      discount:
        type: number
      discountRate:
        type: number
      estGrossMargin:
        description: EstGrossMargin = estProfit / estBillAmount % (to nearest whole
          number)
        type: number
      estInLabour:
        description: EstInLabour is the estimated input labour amount ($); sum of
          estInLabour for all non-deleted timeallocations
        type: number
      estInTotal:
        description: EstInTotal is the estimated input/cost total = estInLabour +
          outUnitTotal
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        description: EstOutLabour is the estimated output labour amount ($); sum of
          estOutLabour for all non-deleted timeallocations
        type: number
      estProfit:
        description: EstProfit = estBillAmount - estInTotal = (estOutLabour + outUnitTotal)
          - (estInLabour + outUnitTotal)
        type: number
      hourlyrateserviceid:
        type: integer
      id:
        description: Core identity
        type: integer
      inAccountingCodeId:
        type: integer
      inLabourPrice:
        description: InLabourPrice is the internal (cost) price of labour for this
          item
        type: number
      inTaxCodeId:
        description: Tax & accounting
        type: integer
      inTaxRate:
        type: number
      inUnitId:
        description: Units
        type: integer
      inUnitPrice:
        description: Sensitive financial fields — pointer types required for NilSensitiveFields
        type: number
      inUnitQty:
        type: number
      inUnitTotal:
        description: InUnitTotal is the input unit line total = inUnitPrice * inUnitQty
        type: number
      invoiceid:
        description: Relationships
        type: integer
      isDiscountPercent:
        type: boolean
      itemcollectionid:
        type: integer
      itemtypeid:
        type: integer
      lastmodifiedutc:
        type: string
      manualBillAmount:
        type: number
      manualBudget:
        type: number
      name:
        description: Basic info
        type: string
      outAccountingCodeId:
        type: integer
      outLabourPrice:
        description: OutLabourPrice is the sale price for labour
        type: number
      outLabourPriceMultiplier:
        type: number
      outTaxCodeId:
        type: integer
      outTaxRate:
        type: number
      outUnitId:
        type: integer
      outUnitPrice:
        type: number
      outUnitPriceMultiplier:
        type: number
      outUnitQty:
        type: number
      outUnitTotal:
        description: OutUnitTotal is the output unit line total = outUnitPrice * outUnitQty
        type: number
      parentid:
        type: integer
      productid:
        type: integer
      sortorder:
        type: string
      timeBillable:
        type: number
      timeallocated:
        description: Time
        type: number
      timespent:
        type: number
      trackingOptionId:
        items:
          type: integer
        type: array
      uniquetoken:
        type: string
      updatedAt:
        type: number
    type: object
  handlers.InvoiceItemUpdatePayload:
    properties:
      billAmount:
        type: number
      billable:
        type: boolean
      name:
        example: Homepage Design
        type: string
    type: object
  handlers.InvoiceListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.InvoiceResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.InvoicePhaseGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.InvoicePhaseResponse'
      status:
        example: success
        type: string
    type: object
  handlers.InvoicePhaseListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.InvoicePhaseResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.InvoicePhaseResponse:
    properties:
      billAmount:
        description: BillAmount is calculated based on BillType config
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item rates and quantities, 2 = fixed fee, 3 = unit prices,
          4 = item rates, 5 = hours spent and quantities, 8 = hours spent
        type: integer
      budget:
        description: Budget is calculated based on BudgetType config
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals, 3 = unit prices, 4 = item rates'
        type: integer
      datecreated:
        example: 2024-01-10T09:00:00
        type: string
      deleted:
        example: false
        type: boolean
      discount:
        type: number
      estGrossMargin:
        description: EstGrossMargin = estProfit / estBillAmount % (to nearest whole
          number)
        type: number
      estInLabour:
        description: EstInLabour is the estimated input labour amount ($); sum of
          estInLabour for all non-deleted timeallocations
        type: number
      estInTotal:
        description: EstInTotal is the estimated input/cost total = estInLabour +
          outUnitTotal
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        description: EstOutLabour is the estimated output labour amount ($); sum of
          estOutLabour for all non-deleted timeallocations
        type: number
      estProfit:
        description: EstProfit = estBillAmount - estInTotal = (estOutLabour + outUnitTotal)
          - (estInLabour + outUnitTotal)
        type: number
      id:
        description: Core identity
        example: 5
        type: integer
      inUnitTotal:
        description: InUnitTotal is the input unit line total = inUnitPrice * inUnitQty
        type: number
      invoiceid:
        description: Relationships
        example: 42
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        description: Basic info
        example: Phase 1
        type: string
      outUnitTotal:
        description: OutUnitTotal is the output unit line total = outUnitPrice * outUnitQty
        type: number
      parentid:
        example: 0
        type: integer
      projectedInLabour:
        type: number
      projectedInTotal:
        type: number
      timeBillable:
        description: Sensitive financial fields — pointer types required for NilSensitiveFields
        type: number
      timeallocated:
        description: Time (non-sensitive)
        type: number
    type: object
  handlers.InvoiceResponse:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      activeworkstate:
        description: Status
        example: draft
        type: string
      address1:
        description: Address (single-get only)
        example: 123 Main Street
        type: string
      address2:
        example: Suite 100
        type: string
      address3:
        example: ""
        type: string
      billAmount:
        example: 5000
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        example: 5750
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item totals, 2 = fixed fee, 3 = unit prices,
          4 = item labour values, 5 = time spent, 6 = fixed amount per phase,
          7 = fixed amount per project, 8 = item labour values (tracked time only)
        example: 1
        type: integer
      budget:
        example: 5000
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        example: 5750
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals'
        example: 1
        type: integer
      city:
        example: New York
        type: string
      clientcontactname:
        description: Client details (single-get only)
        example: John Doe
        type: string
      companyid:
        description: Company
        example: 5
        type: integer
      companyname:
        example: Acme Corp
        type: string
      country:
        example: United States
        type: string
      customfieldname:
        example: Reference
        type: string
      customfieldvalue:
        example: REF-001
        type: string
      description:
        description: Description (requires Invoices JOIN)
        example: Invoice for website design services
        type: string
      duedate:
        example: 2024-02-15T00:00:00
        type: string
      emaileddate:
        example: 2024-01-16T00:00:00
        type: string
      emailedto:
        example: client@example.com
        type: string
      emailedtoclient:
        description: Flags
        example: true
        type: boolean
      grandtotal:
        example: 1150
        type: number
      id:
        example: 42
        type: integer
      invoicedby:
        description: Invoiced by (contact name)
        example: Jane Doe
        type: string
      invoiceddate:
        description: Dates
        example: 2024-01-15T00:00:00
        type: string
      invoicetermid:
        description: Payment terms (single-get only)
        example: 1
        type: integer
      itemsDiscount:
        description: Financial detail (sensitive; single-get and fields=all only)
        example: 0
        type: number
      lastmodifiedutc:
        description: Audit
        example: 2024-01-18T13:20:00
        type: string
      number:
        description: Core
        example: INV-001
        type: string
      pagetitle:
        example: Invoice
        type: string
      paid:
        example: false
        type: boolean
      paiddate:
        example: 2024-02-10T00:00:00
        type: string
      paymentterms:
        example: Net 30
        type: string
      phases:
        description: Sub-entities — populated only when IncludePhases=true (via OUTER
          APPLY in main query)
        items:
          $ref: '#/definitions/handlers.InvoiceSubPhaseItem'
        type: array
      projectid:
        description: Project
        items:
          type: integer
        type: array
      projectnumbers:
        example: PRJ-001
        type: string
      projecttitles:
        example: Website Redesign
        type: string
      purchaseordernumber:
        description: Other
        example: PO-12345
        type: string
      showcostbreakdown:
        example: false
        type: boolean
      showitemdescription:
        example: true
        type: boolean
      showphases:
        example: true
        type: boolean
      state:
        example: NY
        type: string
      subtotal:
        description: Financial totals
        example: 1000
        type: number
      taxable:
        description: Tax (requires JOINs)
        example: true
        type: boolean
      taxrate:
        example: 15
        type: number
      taxtotal:
        example: 150
        type: number
      template:
        example: false
        type: boolean
      timeBillable:
        description: TimeBillable is the aggregate sum of ItemAllocation.timeBillable
        example: 480
        type: integer
      title:
        example: Website Design Invoice
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.InvoiceSubItemItem:
    properties:
      activeworkstate:
        example: active
        type: string
      billAmount:
        example: 1000
        type: number
      billAmountTax:
        example: 1150
        type: number
      billType:
        example: 1
        type: integer
      billable:
        example: true
        type: boolean
      budget:
        example: 1000
        type: number
      budgetTax:
        example: 1150
        type: number
      budgetType:
        example: 1
        type: integer
      code:
        example: ITEM-001
        type: string
      contactid:
        items:
          type: integer
        type: array
      deleted:
        example: false
        type: boolean
      discount:
        example: 0
        type: number
      estInTotal:
        example: 500
        type: number
      estInTotalTax:
        example: 575
        type: number
      id:
        example: 1
        type: integer
      inUnitTotal:
        example: 500
        type: number
      invoiceid:
        example: 42
        type: integer
      itemcollectionid:
        example: 5
        type: integer
      itemtypeid:
        example: 1
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Web Design
        type: string
      outUnitTotal:
        example: 1000
        type: number
      parentid:
        example: 0
        type: integer
      timeBillable:
        example: 120
        type: integer
      timeallocated:
        example: 120
        type: integer
      trackingOptionId:
        items:
          type: integer
        type: array
    type: object
  handlers.InvoiceSubPhaseItem:
    properties:
      billAmount:
        example: 5000
        type: number
      billAmountTax:
        example: 5750
        type: number
      billType:
        example: 1
        type: integer
      budget:
        example: 5000
        type: number
      budgetTax:
        example: 5750
        type: number
      budgetType:
        example: 1
        type: integer
      deleted:
        example: false
        type: boolean
      discount:
        example: 0
        type: number
      estGrossMargin:
        example: 60
        type: number
      estInLabour:
        example: 2000
        type: number
      estInTotal:
        example: 2000
        type: number
      estInTotalTax:
        example: 2300
        type: number
      estOutLabour:
        example: 5000
        type: number
      estProfit:
        example: 3000
        type: number
      id:
        example: 5
        type: integer
      inUnitTotal:
        example: 2000
        type: number
      invoiceid:
        example: 42
        type: integer
      items:
        items:
          $ref: '#/definitions/handlers.InvoiceSubItemItem'
        type: array
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Phase 1
        type: string
      outUnitTotal:
        example: 5000
        type: number
      parentid:
        example: 0
        type: integer
      projectedInLabour:
        example: 2000
        type: number
      projectedInTotal:
        example: 2000
        type: number
      timeBillable:
        example: 480
        type: integer
      timeallocated:
        example: 480
        type: integer
    type: object
  handlers.InvoiceTemplateListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.InvoiceTemplateResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.InvoiceTemplateResponse:
    properties:
      id:
        type: integer
      taxable:
        example: true
        type: boolean
      taxrate:
        example: 15
        type: number
      title:
        example: Standard Invoice
        type: string
    type: object
  handlers.InvoiceWorkStageHistoryListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.InvoiceWorkStageHistoryResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.InvoiceWorkStageHistoryResponse:
    properties:
      contactid:
        example: 10
        type: integer
      deleted:
        example: false
        type: boolean
      id:
        example: 1
        type: integer
      invoiceid:
        example: 42
        type: integer
      name:
        example: Approved
        type: string
      setdatetime:
        example: 2024-01-18T13:20:00
        type: string
      workstageid:
        example: 3
        type: integer
    type: object
  handlers.ItemCategoryGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ItemCategoryResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ItemCategoryListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ItemCategoryResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ItemCategoryResponse:
    properties:
      color:
        example: A4C0DE
        type: string
      id:
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Design
        type: string
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.ItemTagGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ItemTagResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ItemTagListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ItemTagResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ItemTagResponse:
    properties:
      color:
        example: A4C0DE
        type: string
      id:
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Urgent
        type: string
    type: object
  handlers.ItemWorkStageHistoryListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ItemWorkStageHistoryResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ItemWorkStageHistoryResponse:
    properties:
      active:
        example: true
        type: boolean
      contactid:
        example: 10
        type: integer
      id:
        example: 1
        type: integer
      itemcontactid:
        example: "10"
        type: string
      itemid:
        example: 5
        type: integer
      name:
        example: In Progress
        type: string
      setdatetime:
        example: 2024-01-18T13:20:00
        type: string
      workstageid:
        example: 3
        type: integer
    type: object
  handlers.ItemsToTagsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      itemid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.LicenseDetails:
    properties:
      available:
        example: 90
        type: integer
      total:
        example: 100
        type: integer
      used:
        example: 10
        type: integer
    type: object
  handlers.LicenseGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.LicenseDetails'
      status:
        example: success
        type: string
    type: object
  handlers.LooknfeelListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.LooknfeelResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.LooknfeelResponse:
    properties:
      colorscheme:
        example: blue
        type: string
      headerprimary:
        example: '#1A5276'
        type: string
      headersecondary:
        example: '#2E86C1'
        type: string
      headertext:
        example: '#FFFFFF'
        type: string
      id:
        example: 1
        type: integer
      linktext:
        example: '#1A5276'
        type: string
      logo:
        example: https://example.com/img/logo.png
        type: string
      tab:
        example: '#1A5276'
        type: string
      tabhover:
        example: '#2E86C1'
        type: string
    type: object
  handlers.MeDetailResponse:
    properties:
      address1:
        example: 123 Main St
        type: string
      address2:
        example: Suite 100
        type: string
      address3:
        example: ""
        type: string
      allowlogin:
        example: true
        type: boolean
      city:
        example: New York
        type: string
      companyid:
        example: 1
        type: integer
      companyname:
        example: Acme Corp
        type: string
      country:
        example: USA
        type: string
      defaulthourlyrateid:
        example: 1
        type: integer
      divisionid:
        example: 1
        type: integer
      email:
        example: john@example.com
        type: string
      fax:
        example: 123-456-7892
        type: string
      firstname:
        example: John
        type: string
      groups:
        items:
          $ref: '#/definitions/handlers.ContactSubGroup'
        type: array
      ianatimezone:
        example: Pacific/Auckland
        type: string
      id:
        example: 1
        type: integer
      image:
        example: https://cdn.proworkflow.com/images/contact/1.jpg
        type: string
      invoicesplugin:
        example: true
        type: boolean
      lastmodifiedutc:
        example: 2024-01-15T15:30:00
        type: string
      lastname:
        example: Smith
        type: string
      mobilephone:
        example: 123-456-7891
        type: string
      notes:
        items:
          $ref: '#/definitions/handlers.ContactSubNote'
        type: array
      payrate:
        example: 50
        type: number
      payratemultiplier:
        example: 1.5
        type: number
      pending:
        example: false
        type: boolean
      plan:
        example: Advanced
        type: string
      quotesplugin:
        example: true
        type: boolean
      roles:
        items:
          $ref: '#/definitions/handlers.ContactSubRole'
        type: array
      state:
        example: NY
        type: string
      status:
        example: active
        type: string
      tags:
        items:
          $ref: '#/definitions/handlers.ContactSubTag'
        type: array
      teams:
        items:
          $ref: '#/definitions/handlers.ContactSubTeam'
        type: array
      title:
        example: CEO
        type: string
      type:
        example: staff
        type: string
      username:
        example: jsmith
        type: string
      workphone:
        example: 123-456-7890
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.MeGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.MeDetailResponse'
      status:
        example: success
        type: string
    type: object
  handlers.MessageContactsPayload:
    properties:
      contactid:
        example:
        - 4
        - 5
        - 6
        items:
          type: integer
        type: array
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.MessageGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.MessageResponse'
      status:
        example: success
        type: string
    type: object
  handlers.MessageListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.MessageResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.MessageReplyItem:
    properties:
      authorid:
        example: 3
        type: integer
      authorimage:
        example: https://example.com/img/contactimages/john.png
        type: string
      authorname:
        example: John Smith
        type: string
      authortype:
        example: staff
        type: string
      content:
        example: Thanks for the update.
        type: string
      date:
        example: 2024-01-18T14:00:00
        type: string
      files:
        example: 10,11
        type: string
      id:
        example: 2
        type: integer
    type: object
  handlers.MessageResponse:
    properties:
      authoremail:
        example: jane@example.com
        type: string
      authorid:
        example: 2
        type: integer
      authorimage:
        example: https://example.com/img/contactimages/jane.png
        type: string
      authorname:
        example: Jane Smith
        type: string
      authortype:
        example: staff
        type: string
      contacts:
        example: 1,2,3
        type: string
      content:
        example: Here is the latest update...
        type: string
      date:
        example: 2024-01-18T13:20:00
        type: string
      files:
        example: 10,11
        type: string
      filesenabled:
        example: "true"
        type: string
      id:
        example: 1
        type: integer
      itemid:
        example: 5
        type: integer
      itemname:
        example: Design mockups
        type: string
      originalmessageid:
        example: 0
        type: integer
      projectcontacts:
        example: 1,2,3
        type: string
      projectid:
        example: 10
        type: integer
      projectmanagerid:
        example: 2
        type: integer
      projectmanagername:
        example: Jane Smith
        type: string
      projectnumber:
        example: PRJ-001
        type: string
      projecttitle:
        example: Website Redesign
        type: string
      public:
        example: false
        type: boolean
      replies:
        description: Sub-entities — populated only when IncludeReplies=true (single-get
          always; list opt-in)
        items:
          $ref: '#/definitions/handlers.MessageReplyItem'
        type: array
      replycount:
        example: 3
        type: integer
      subject:
        example: Project update
        type: string
    type: object
  handlers.MoveItemsRequest:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      itemcollectionid:
        example: 456
        type: integer
    type: object
  handlers.PermissionSettingsListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.PermissionSettingsResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.PermissionSettingsResponse:
    properties:
      description:
        example: Allows user to create and manage companies
        type: string
      id:
        example: 8
        type: integer
      name:
        example: Manage Companies
        type: string
      viewonly:
        example: false
        type: boolean
    type: object
  handlers.PhaseCreatePayload:
    properties:
      name:
        example: Design Phase
        type: string
      parentid:
        type: integer
      projectid:
        type: integer
      sortorder:
        type: integer
    type: object
  handlers.PhaseUpdatePayload:
    properties:
      name:
        example: Design Phase
        type: string
      parentid:
        type: integer
      sortorder:
        type: integer
    type: object
  handlers.PrerequisitesToItemsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      prerequisiteid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.ProjectAccessDetailsResult:
    properties:
      number:
        example: PRJ-001
        type: string
      title:
        example: Website Redesign
        type: string
    type: object
  handlers.ProjectAccessResponse:
    properties:
      access:
        type: boolean
      details:
        $ref: '#/definitions/handlers.ProjectAccessDetailsResult'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectBookmarkGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ProjectBookmarkResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectBookmarkItem:
    properties:
      id:
        example: 1
        type: integer
      projectid:
        example: 1
        type: integer
      title:
        example: Project Reference
        type: string
      url:
        example: https://www.example.com
        type: string
    type: object
  handlers.ProjectBookmarkListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectBookmarkResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectBookmarkResponse:
    properties:
      id:
        example: 1
        type: integer
      projectid:
        example: 10
        type: integer
      title:
        example: Example Site
        type: string
      url:
        example: https://example.com
        type: string
    type: object
  handlers.ProjectCategoryGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ProjectCategoryResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectCategoryListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectCategoryResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectCategoryResponse:
    properties:
      color:
        example: A4C0DE
        type: string
      id:
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Marketing
        type: string
      projectcount:
        example: 5
        type: integer
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.ProjectContactItem:
    properties:
      firstname:
        example: John
        type: string
      id:
        example: 1
        type: integer
      lastname:
        example: Smith
        type: string
      name:
        example: John Smith
        type: string
      type:
        example: staff
        type: string
    type: object
  handlers.ProjectCustomFieldInput:
    properties:
      customfieldid:
        description: ID of the custom field definition.
        example: 1
        type: integer
      customfieldoptionid:
        description: Option ID for dropdown type fields. Alternatively pass the option
          ID as value.
        example: 5
        type: integer
      type:
        description: Type of the custom field.
        enum:
        - checkbox
        - date
        - dropdown
        - number
        - percentage
        - rating
        - staff
        - text
        example: text
        type: string
      value:
        description: |-
          Value for the custom field. Pass as a string for checkbox ("checked"/"unchecked"),
          date ("YYYY-MM-DD"), rating, and text types. Pass as a number for number, percentage,
          staff (contact ID), and dropdown (customfieldoption ID) types.
        example: some text
        type: string
    type: object
  handlers.ProjectCustomFieldItem:
    properties:
      id:
        example: 1
        type: integer
      name:
        example: Priority Level
        type: string
      type:
        example: dropdown
        type: string
      value:
        example: High
        type: string
      valuename:
        example: High Priority
        type: string
    type: object
  handlers.ProjectFileItem:
    properties:
      description:
        example: Homepage design mockup
        type: string
      folderid:
        example: 1
        type: integer
      id:
        example: 1
        type: integer
      modified:
        example: 2024-01-15T10:00:00
        type: string
      name:
        example: homepage-mockup.pdf
        type: string
      ownerid:
        example: 1
        type: integer
      projectid:
        example: 1
        type: integer
      size:
        example: 204800
        type: integer
      taskid:
        example: 1
        type: integer
      uniquetoken:
        example: abc123
        type: string
    type: object
  handlers.ProjectFolderItem:
    properties:
      contactid:
        items:
          type: integer
        type: array
      description:
        example: All design-related files
        type: string
      id:
        example: 1
        type: integer
      modified:
        example: 2024-01-15T10:00:00
        type: string
      name:
        example: Design Assets
        type: string
      ownerid:
        example: 1
        type: integer
      projectid:
        example: 1
        type: integer
      public:
        example: true
        type: boolean
      size:
        example: 1048576
        type: integer
      taskid:
        example: 0
        type: integer
      type:
        example: project
        type: string
    type: object
  handlers.ProjectGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ProjectResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectInvoiceItem:
    properties:
      activeworkstate:
        example: draft
        type: string
      companyid:
        example: 5
        type: integer
      duedate:
        example: "2024-02-15"
        type: string
      grandtotal:
        example: 1150
        type: number
      id:
        example: 1
        type: integer
      invoicedate:
        example: "2024-01-15"
        type: string
      number:
        example: INV-001
        type: string
      paid:
        example: false
        type: boolean
      paiddate:
        example: ""
        type: string
      projectid:
        example: 1
        type: integer
      subtotal:
        example: 1000
        type: number
      title:
        example: Website Design Invoice
        type: string
    type: object
  handlers.ProjectItemGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ProjectItemResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectItemListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectItemResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectItemResponse:
    properties:
      activeworkstageid:
        description: Status & scheduling
        type: integer
      activeworkstate:
        type: string
      actualInLabour:
        description: |-
          Actual (sensitive)
          ActualInLabour is the actual input labour amount = inLabourPrice * timeSpent/60
        type: number
      actualInTotal:
        description: ActualInTotal is the actual input/cost total = actualInLabour
          + outUnitTotal
        type: number
      actualInTotalTax:
        type: number
      actualOutLabour:
        description: ActualOutLabour is the actual output labour amount = outLabourPrice
          * timeSpent/60
        type: number
      actualProfit:
        description: ActualProfit = projectedBillAmount - actualInTotal = (actualOutLabour
          + outUnitTotal) - (actualInLabour + outUnitTotal)
        type: number
      billAmount:
        description: BillAmount is calculated based on BillType config
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item rates and quantities, 2 = fixed fee, 3 = unit prices,
          4 = item rates, 5 = hours spent and quantities, 8 = hours spent
        type: integer
      billable:
        type: boolean
      budget:
        description: Budget is calculated based on BudgetType config
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals, 3 = unit prices, 4 = item rates'
        type: integer
      categoryid:
        type: integer
      chargeRateType:
        description: |-
          ChargeRateType determines how output costs are calculated:
          1 (Single Rate) = use outLabourPrice; 2 (Split Rate) = use outLabourPrice of linked hourly rate services; 0 = no charge rate tracking
        type: string
      code:
        type: string
      companyid:
        type: integer
      companyname:
        type: string
      completedate:
        type: string
      contactid:
        description: Relationship ID arrays
        items:
          type: integer
        type: array
      contacts:
        description: JSON array fields (OUTER APPLY)
        items:
          type: integer
        type: array
      costRateType:
        description: |-
          CostRateType determines how input costs are calculated:
          1 (Staff Rate) = use rate of linked staff members; 2 (Service Rate) = use rate of linked hourly rate services; 0 = no cost rate tracking
        type: string
      createdatetime:
        type: string
      creatorid:
        type: integer
      deleted:
        type: boolean
      dependenttaskid:
        items:
          type: integer
        type: array
      description:
        type: string
      discount:
        description: Discount (sensitive)
        type: number
      discountRate:
        type: number
      duedate:
        type: string
      effortScoreId:
        type: integer
      estBillAmount:
        description: EstBillAmount represents billAmount without using actual values
          (always estimated)
        type: number
      estBillAmountTax:
        description: EstBillAmountTax is the tax on estBillAmount
        type: number
      estGrossMargin:
        description: EstGrossMargin = estProfit / estBillAmount % (to nearest whole
          number)
        type: number
      estInLabour:
        description: |-
          Estimated (sensitive)
          EstInLabour is the estimated input labour amount ($); sum of estInLabour for all non-deleted timeallocations
        type: number
      estInTotal:
        description: EstInTotal is the estimated input/cost total = estInLabour +
          outUnitTotal
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        description: EstOutLabour is the estimated output labour amount ($); sum of
          estOutLabour for all non-deleted timeallocations
        type: number
      estProfit:
        description: |-
          Profit (sensitive)
          EstProfit = estBillAmount - estInTotal = (estOutLabour + outUnitTotal) - (estInLabour + outUnitTotal)
        type: number
      hourlyrateserviceid:
        type: integer
      id:
        description: Core identity
        type: integer
      impactScoreId:
        type: integer
      importanceScoreId:
        type: integer
      inAccountingCodeId:
        type: integer
      inLabourPrice:
        description: InLabourPrice is the internal (cost) price of labour for this
          item
        type: number
      inTaxCodeId:
        type: integer
      inTaxRate:
        type: number
      inUnitId:
        description: Units & tax
        type: integer
      inUnitPrice:
        type: number
      inUnitQty:
        type: number
      inUnitTotal:
        description: InUnitTotal is the input unit line total = inUnitPrice * inUnitQty
        type: number
      invoicedAmount:
        description: |-
          Invoiced
          InvoicedAmount is the dollar value that has been invoiced (may span multiple invoices)
        type: number
      invoicedAmountTax:
        description: InvoicedAmountTax is the tax amount that has been invoiced (may
          span multiple invoices)
        type: number
      invoiceitemid:
        items:
          type: integer
        type: array
      isDiscountPercent:
        type: boolean
      itemcollectionid:
        type: integer
      itemtypeid:
        type: integer
      lastmodifiedutc:
        type: string
      manualBillAmount:
        description: Billing (sensitive)
        type: number
      manualBudget:
        description: Budget (sensitive)
        type: number
      manualPercentageComplete:
        type: number
      name:
        description: Basic info
        type: string
      number:
        type: integer
      outAccountingCodeId:
        type: integer
      outLabourPrice:
        description: |-
          Units/pricing (sensitive)
          OutLabourPrice is the sale price for labour
        type: number
      outLabourPriceMultiplier:
        type: number
      outTaxCodeId:
        type: integer
      outTaxRate:
        type: number
      outUnitId:
        type: integer
      outUnitPrice:
        type: number
      outUnitPriceMultiplier:
        type: number
      outUnitQty:
        type: number
      outUnitTotal:
        description: OutUnitTotal is the output unit line total = outUnitPrice * outUnitQty
        type: number
      paidAmount:
        description: PaidAmount is the dollar value in invoices marked as paid (may
          span multiple invoices)
        type: number
      paidAmountTax:
        description: PaidAmountTax is the tax amount that has been paid (may span
          multiple invoices)
        type: number
      parentid:
        type: integer
      phasename:
        type: string
      prerequisiteid:
        items:
          type: integer
        type: array
      priorityid:
        type: integer
      productid:
        type: integer
      projectedBillAmount:
        description: |-
          Projected billing (sensitive)
          ProjectedBillAmount represents billAmount adjusted for projectedOutTotal values
        type: number
      projectedBillAmountTax:
        description: ProjectedBillAmountTax is the tax on projectedBillAmount
        type: number
      projectedGrossMargin:
        description: ProjectedGrossMargin = projectedProfit / projectedOutTotal %
          (to nearest whole number)
        type: number
      projectedInLabour:
        description: Projections
        type: number
      projectedInTotal:
        type: number
      projectedOutLabour:
        type: number
      projectedProfit:
        description: ProjectedProfit = estBillAmount - projectedInTotal (difference
          between expected total revenue and projected costs)
        type: number
      projectedTimeManual:
        type: number
      projectedTimeSpent:
        type: number
      projectid:
        description: Relationships
        type: integer
      projectnumber:
        type: string
      projecttitle:
        type: string
      quoteitemid:
        items:
          type: integer
        type: array
      startdate:
        type: string
      storyPoints:
        description: Scoring
        type: integer
      tagid:
        items:
          type: integer
        type: array
      tags:
        items:
          type: integer
        type: array
      timeBillable:
        type: integer
      timeallocated:
        description: Time
        type: integer
      timespent:
        type: integer
      trackingOptionId:
        items:
          type: integer
        type: array
      uniquetoken:
        type: string
      urgencyScoreId:
        type: integer
    type: object
  handlers.ProjectListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectManagementTeam:
    properties:
      groupid:
        example: 1
        type: integer
      managerid:
        example: 1
        type: integer
      teamid:
        example: 1
        type: integer
    type: object
  handlers.ProjectMessageItem:
    properties:
      contactid:
        example:
        - 1
        items:
          type: integer
        type: array
      id:
        example: 1
        type: integer
      itemid:
        example: 1
        type: integer
      projectid:
        example: 1
        type: integer
      public:
        example: true
        type: boolean
      replycount:
        example: 3
        type: integer
      senddate:
        example: 2024-01-15T10:00:00
        type: string
      senderid:
        example: 1
        type: integer
      shortdetails:
        example: Homepage design is complete
        type: string
      subject:
        example: Project update
        type: string
      type:
        example: message
        type: string
    type: object
  handlers.ProjectNoteCreatePayload:
    properties:
      content:
        example: Discussed homepage layout and colour palette.
        type: string
      description:
        example: Notes from the 15 Jan kickoff meeting.
        type: string
      projectid:
        type: integer
      title:
        example: Meeting Notes
        type: string
    type: object
  handlers.ProjectNoteListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectNoteResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectNoteResponse:
    properties:
      companyid:
        example: 5
        type: integer
      companyname:
        example: Acme Corp
        type: string
      content:
        example: Discussed homepage layout and colour palette.
        type: string
      id:
        example: 1
        type: integer
      lastmodifiedutc:
        example: 2024-01-15T15:30:00
        type: string
      projectid:
        example: 1
        type: integer
      projectnumber:
        example: PRJ-001
        type: string
      projecttitle:
        example: Website Redesign
        type: string
      title:
        example: Meeting Notes
        type: string
    type: object
  handlers.ProjectNoteUpdatePayload:
    properties:
      content:
        example: Discussed homepage layout and colour palette.
        type: string
      description:
        example: Notes from the 15 Jan kickoff meeting.
        type: string
      title:
        example: Meeting Notes
        type: string
    type: object
  handlers.ProjectPhaseGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ProjectPhaseResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectPhaseListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectPhaseResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectPhaseResponse:
    properties:
      actualInLabour:
        description: ActualInLabour is the actual input labour amount = inLabourPrice
          * timeSpent/60
        type: number
      actualInTotal:
        description: ActualInTotal is the actual input/cost total = actualInLabour
          + outUnitTotal
        type: number
      actualInTotalTax:
        type: number
      actualOutLabour:
        description: ActualOutLabour is the actual output labour amount = outLabourPrice
          * timeSpent/60
        type: number
      actualProfit:
        description: ActualProfit = projectedBillAmount - actualInTotal = (actualOutLabour
          + outUnitTotal) - (actualInLabour + outUnitTotal)
        type: number
      billAmount:
        description: BillAmount is calculated based on BillType config
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item rates and quantities, 2 = fixed fee, 3 = unit prices,
          4 = item rates, 5 = hours spent and quantities, 8 = hours spent
        type: integer
      budget:
        description: Budget is calculated based on BudgetType config
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals, 3 = unit prices, 4 = item rates'
        type: integer
      datecreated:
        example: 2024-01-10T09:00:00
        type: string
      deleted:
        example: false
        type: boolean
      discount:
        type: number
      duedate:
        example: 2024-02-15T00:00:00
        type: string
      estBillAmount:
        description: EstBillAmount represents billAmount without using actual values
          (always estimated)
        type: number
      estBillAmountTax:
        description: EstBillAmountTax is the tax on estBillAmount
        type: number
      estGrossMargin:
        description: EstGrossMargin = estProfit / estBillAmount % (to nearest whole
          number)
        type: number
      estInLabour:
        description: EstInLabour is the estimated input labour amount ($); sum of
          estInLabour for all non-deleted timeallocations
        type: number
      estInTotal:
        description: EstInTotal is the estimated input/cost total = estInLabour +
          outUnitTotal
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        description: EstOutLabour is the estimated output labour amount ($); sum of
          estOutLabour for all non-deleted timeallocations
        type: number
      estProfit:
        description: EstProfit = estBillAmount - estInTotal = (estOutLabour + outUnitTotal)
          - (estInLabour + outUnitTotal)
        type: number
      id:
        description: Core identity
        example: 1
        type: integer
      inUnitTotal:
        description: InUnitTotal is the input unit line total = inUnitPrice * inUnitQty
        type: number
      invoicedAmount:
        description: InvoicedAmount is the dollar value that has been invoiced (may
          span multiple invoices)
        type: number
      invoicedAmountTax:
        description: InvoicedAmountTax is the tax amount that has been invoiced (may
          span multiple invoices)
        type: number
      invoiceitemcollectionid:
        items:
          type: integer
        type: array
      itemsActive:
        example: 2
        type: integer
      itemsCompleted:
        example: 3
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        description: Basic info
        example: Design Phase
        type: string
      outUnitTotal:
        description: OutUnitTotal is the output unit line total = outUnitPrice * outUnitQty
        type: number
      paidAmount:
        description: PaidAmount is the dollar value in invoices marked as paid (may
          span multiple invoices)
        type: number
      paidAmountTax:
        description: PaidAmountTax is the tax amount that has been paid (may span
          multiple invoices)
        type: number
      parentid:
        example: 0
        type: integer
      projectedBillAmount:
        description: ProjectedBillAmount represents billAmount adjusted for projectedOutTotal
          values
        type: number
      projectedBillAmountTax:
        description: ProjectedBillAmountTax is the tax on projectedBillAmount
        type: number
      projectedGrossMargin:
        description: ProjectedGrossMargin = projectedProfit / projectedOutTotal %
          (to nearest whole number)
        type: number
      projectedProfit:
        description: ProjectedProfit = estBillAmount - projectedInTotal (difference
          between expected total revenue and projected costs)
        type: number
      projectedTimeManual:
        description: ProjectedTimeManual is the projected total time expected to take
          to complete the phase
        type: number
      projectedTimeSpent:
        type: number
      projectid:
        description: Relationships
        example: 10
        type: integer
      quoteitemcollectionid:
        items:
          type: integer
        type: array
      startdate:
        example: 2024-01-15T00:00:00
        type: string
      storyPoints:
        description: Progress (non-sensitive)
        example: 13
        type: number
      timeBillable:
        description: Sensitive financial fields — pointer types required for NilSensitiveFields
        type: number
      timeallocated:
        type: number
      timespent:
        type: number
    type: object
  handlers.ProjectProjectNoteItem:
    properties:
      content:
        example: Discussed homepage layout and colour palette.
        type: string
      id:
        example: 1
        type: integer
      title:
        example: Meeting Notes
        type: string
    type: object
  handlers.ProjectResponse:
    properties:
      activeworkstate:
        example: active
        type: string
      actualInLabour:
        description: |-
          actual (sensitive)
          ActualInLabour is the actual input labour amount = inLabourPrice * timeSpent/60
        type: number
      actualInTotal:
        description: ActualInTotal is the actual input/cost total = actualInLabour
          + outUnitTotal
        type: number
      actualInTotalTax:
        type: number
      actualOutLabour:
        description: ActualOutLabour is the actual output labour amount = outLabourPrice
          * timeSpent/60
        type: number
      billAmount:
        description: BillAmount is calculated based on BillType config
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        type: number
      billType:
        description: |-
          billing detail (sensitive)
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item totals, 2 = fixed fee, 3 = unit prices,
          4 = item labour values, 5 = time spent, 6 = fixed amount per phase,
          7 = fixed amount per project, 8 = item labour values (tracked time only)
        type: integer
      billtotal:
        example: 8000
        type: number
      bookmarks:
        items:
          $ref: '#/definitions/handlers.ProjectBookmarkItem'
        type: array
      budget:
        description: financial (composite summary fields)
        example: 10000
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        type: number
      budgetType:
        description: |-
          budget detail (sensitive)
          BudgetType determines how budget is calculated: 0 = no budget, 1 = item totals
        type: integer
      burn:
        example: 5000
        type: number
      categoryid:
        description: category
        example: 1
        type: integer
      categoryname:
        example: Web Projects
        type: string
      chargeRateType:
        description: |-
          ChargeRateType determines the default chargeRateType for new items:
          1 = Single Rate, 2 = Split Rate
        type: integer
      clientaccess:
        description: access/UI settings
        type: boolean
      clientid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      clients:
        items:
          $ref: '#/definitions/handlers.ProjectContactItem'
        type: array
      clienttype:
        description: IsClassic       *bool   `json:"isclassic,omitempty"`
        example: external
        type: string
      clientviewalltasks:
        type: boolean
      clientviewtime:
        type: boolean
      companyid:
        description: company
        example: 5
        type: integer
      companyname:
        example: Acme Corp
        type: string
      completedate:
        example: "2024-04-01"
        type: string
      contactid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      contractorid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      contractors:
        items:
          $ref: '#/definitions/handlers.ProjectContactItem'
        type: array
      costRateType:
        description: |-
          CostRateType determines the default costRateType for new items:
          0 = No Cost Tracking, 1 = Staff Cost Rate, 2 = Hourly Service Cost Rate
        type: integer
      createdate:
        example: "2024-01-10"
        type: string
      customfieldoptionid:
        description: |-
          ICalContactIDs       *models.IntArray          `json:"icalcontactid,omitempty"`
          IntegrationFolderIDs *models.IntArray          `json:"integrationfolderid,omitempty"`
        items:
          type: integer
        type: array
      customfields:
        description: customfields — typed array of {id, name, type, value, valuename}
        items:
          $ref: '#/definitions/handlers.ProjectCustomFieldItem'
        type: array
      deleted:
        description: metadata
        type: boolean
      description:
        description: description
        example: Complete website redesign project
        type: string
      divisionid:
        description: divisionid
        type: integer
      duedate:
        example: "2024-03-15"
        type: string
      estBillAmount:
        description: EstBillAmount represents billAmount without using actual values
          (always estimated)
        type: number
      estBillAmountTax:
        description: EstBillAmountTax is the tax on estBillAmount
        type: number
      estGrossMargin:
        description: EstGrossMargin = estProfit / estBillAmount % (to nearest whole
          number)
        type: number
      estInLabour:
        description: |-
          estimated (sensitive)
          EstInLabour is the estimated input labour amount ($); sum of estInLabour for all non-deleted items
        type: number
      estInTotal:
        description: EstInTotal is the estimated input/cost total = estInLabour +
          outUnitTotal
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        description: EstOutLabour is the estimated output labour amount ($); sum of
          estOutLabour for all non-deleted items
        type: number
      estProfit:
        description: |-
          profit (sensitive)
          EstProfit = estBillAmount - estInTotal = (estOutLabour + outUnitTotal) - (estInLabour + outUnitTotal)
        type: number
      files:
        items:
          $ref: '#/definitions/handlers.ProjectFileItem'
        type: array
      folders:
        items:
          $ref: '#/definitions/handlers.ProjectFolderItem'
        type: array
      groupid:
        description: group (Advanced plan)
        example: 1
        type: integer
      groupname:
        example: Creative Group
        type: string
      id:
        description: Always present
        example: 1
        type: integer
      inUnitTotal:
        description: |-
          units (sensitive)
          InUnitTotal is the input unit line total = inUnitPrice * inUnitQty
        type: number
      internalclientcontactid:
        example: 10
        type: integer
      internalclientgroupid:
        example: 3
        type: integer
      internalclientgroupname:
        example: Creative Group
        type: string
      internalclientteamid:
        example: 2
        type: integer
      internalclientteamname:
        example: Design Team
        type: string
      invoiced:
        description: invoiced/paid status flags
        type: boolean
      invoicedAmount:
        description: |-
          invoiced detail (sensitive)
          InvoicedAmount is the dollar value that has been invoiced (may span multiple invoices)
        type: number
      invoicedAmountTax:
        description: InvoicedAmountTax is the tax amount that has been invoiced (may
          span multiple invoices)
        type: number
      invoices:
        items:
          $ref: '#/definitions/handlers.ProjectInvoiceItem'
        type: array
      invoicetotal:
        example: 7500
        type: number
      itemDueDate:
        example: "2024-03-15"
        type: string
      itemStartDate:
        example: "2024-01-15"
        type: string
      itemsActive:
        type: integer
      itemsCompleted:
        type: integer
      itemsDiscount:
        description: discount (sensitive)
        type: number
      lastmodifiedutc:
        description: lastmodified
        example: 2024-01-18T13:20:00
        type: string
      managerfirstname:
        example: John
        type: string
      managerid:
        description: manager
        example: 1
        type: integer
      managerlastname:
        example: Smith
        type: string
      messages:
        items:
          $ref: '#/definitions/handlers.ProjectMessageItem'
        type: array
      notification:
        type: boolean
      number:
        description: number
        example: PRJ-001
        type: string
      outUnitTotal:
        description: OutUnitTotal is the output unit line total = outUnitPrice * outUnitQty
        type: number
      paid:
        type: boolean
      paidAmountTax:
        description: PaidAmountTax is the tax amount that has been paid (may span
          multiple invoices)
        type: number
      paidamount:
        example: 3000
        type: number
      percentcomplete:
        description: percentcomplete (0–100, heading tasks excluded)
        example: 75
        type: integer
      phases:
        description: |-
          sub-entity arrays — only present when the corresponding include param is set.
          Must be pointer types so omitempty can distinguish nil (not requested, column absent
          from SQL) from a non-nil empty slice (requested but no data → emits []).
          The typed-row scanner allocates the pointer before calling Scan, so any column that
          is present in the result set always yields a non-nil pointer even when SQL returns NULL.
        items:
          $ref: '#/definitions/handlers.ProjectSubPhaseItem'
        type: array
      priority:
        description: priority (1=Very High … 5=Very Low)
        example: 2
        type: integer
      privatenotes:
        description: privatenotes
        example: Internal notes
        type: string
      projectedBillAmount:
        description: |-
          projected (billing)
          ProjectedBillAmount represents billAmount adjusted for projectedOutTotal values
        type: number
      projectedBillAmountTax:
        description: ProjectedBillAmountTax is the tax on projectedBillAmount
        type: number
      projectedGrossMargin:
        description: ProjectedGrossMargin = projectedProfit / projectedOutTotal %
          (to nearest whole number)
        type: number
      projectedProfit:
        description: ProjectedProfit = estBillAmount - projectedInTotal (difference
          between expected total revenue and projected costs)
        type: number
      projectedTimeManual:
        description: |-
          projected (sensitive)
          ProjectedTimeManual is the projected total time expected to complete the project
        type: number
      projectedTimeSpent:
        description: ProjectedTimeSpent is the projected time spent
        type: number
      projectnotes:
        items:
          $ref: '#/definitions/handlers.ProjectProjectNoteItem'
        type: array
      purchaseorder:
        example: PO-12345
        type: string
      staff:
        description: contacts — typed arrays of {id, name, firstname, lastname, type}
        items:
          $ref: '#/definitions/handlers.ProjectContactItem'
        type: array
      staffid:
        description: contact CSV lists
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      staffviewalltasks:
        type: boolean
      startdate:
        description: dates
        example: "2024-01-15"
        type: string
      storyPoints:
        description: scoring/aggregates
        type: number
      tagid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      tags:
        description: tags — typed array of {id, name, color}
        items:
          $ref: '#/definitions/handlers.ProjectTagItem'
        type: array
      teamid:
        description: team (Advanced plan)
        example: 1
        type: integer
      teamname:
        example: Dev Team
        type: string
      template:
        type: boolean
      timeBillable:
        description: TimeBillable is the aggregate sum of ItemAllocation.timeBillable
        type: number
      timeallocated:
        description: time (decimal hours)
        example: 40.5
        type: number
      timerecords:
        items:
          $ref: '#/definitions/handlers.ProjectTimeRecordItem'
        type: array
      timetracked:
        example: 35.25
        type: number
      title:
        description: title
        example: Website Redesign
        type: string
      workstageid:
        description: workstage
        example: 1
        type: integer
      workstagename:
        example: Design Phase
        type: string
      workstages:
        items:
          $ref: '#/definitions/handlers.ProjectWorkStageItem'
        type: array
    type: object
  handlers.ProjectSettingsDetailResponse:
    properties:
      clientaccess:
        example: true
        type: boolean
      clientviewalltasks:
        example: false
        type: boolean
      clientviewtime:
        example: false
        type: boolean
      middlecontainerorder:
        example: tasks,phases
        type: string
      notification:
        example: true
        type: boolean
      rightcontainerorder:
        example: messages,files
        type: string
      staffviewalltasks:
        example: true
        type: boolean
    type: object
  handlers.ProjectSettingsGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ProjectSettingsDetailResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectSubItemItem:
    properties:
      activeworkstate:
        example: active
        type: string
      billable:
        example: true
        type: boolean
      code:
        example: TASK-001
        type: string
      completedate:
        example: ""
        type: string
      duedate:
        example: "2024-02-15"
        type: string
      id:
        example: 1
        type: integer
      name:
        example: Design homepage
        type: string
      parentid:
        example: 0
        type: integer
      priorityid:
        example: 3
        type: integer
      startdate:
        example: "2024-01-15"
        type: string
      timeallocated:
        example: 8
        type: integer
      timespent:
        example: 3
        type: integer
    type: object
  handlers.ProjectSubPhaseItem:
    properties:
      duedate:
        example: "2024-02-15"
        type: string
      id:
        example: 1
        type: integer
      items:
        items:
          $ref: '#/definitions/handlers.ProjectSubItemItem'
        type: array
      name:
        example: Design Phase
        type: string
      startdate:
        example: "2024-01-15"
        type: string
    type: object
  handlers.ProjectTagGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ProjectTagResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectTagItem:
    properties:
      color:
        example: '#FF0000'
        type: string
      id:
        example: 1
        type: integer
      name:
        example: VIP
        type: string
    type: object
  handlers.ProjectTagListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectTagResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectTagResponse:
    properties:
      color:
        example: A4C0DE
        type: string
      id:
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Urgent
        type: string
    type: object
  handlers.ProjectTemplateListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectTemplateResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectTemplateResponse:
    properties:
      id:
        type: integer
      title:
        example: Website Redesign Template
        type: string
    type: object
  handlers.ProjectTimeRecordItem:
    properties:
      accountedfor:
        example: true
        type: boolean
      contactid:
        example: 1
        type: integer
      endtime:
        example: "17:00"
        type: string
      id:
        example: 1
        type: integer
      itemid:
        example: 1
        type: integer
      notes:
        example: Working on homepage design
        type: string
      running:
        example: false
        type: boolean
      startdate:
        example: "2024-01-15"
        type: string
      starttime:
        example: "09:00"
        type: string
      timespent:
        example: 8
        type: number
    type: object
  handlers.ProjectWorkStageHistoryListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ProjectWorkStageHistoryResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ProjectWorkStageHistoryResponse:
    properties:
      active:
        example: true
        type: boolean
      contactid:
        example: 10
        type: integer
      deleted:
        example: false
        type: boolean
      id:
        example: 1
        type: integer
      name:
        example: In Progress
        type: string
      projectid:
        example: 15
        type: integer
      setdatetime:
        example: 2024-01-18T13:20:00
        type: string
      workstageid:
        example: 3
        type: integer
    type: object
  handlers.ProjectWorkStageItem:
    properties:
      active:
        example: true
        type: boolean
      contactid:
        example: 10
        type: integer
      deleted:
        example: false
        type: boolean
      id:
        example: 1
        type: integer
      name:
        example: In Progress
        type: string
      projectid:
        example: 15
        type: integer
      setdatetime:
        example: 2024-01-18T13:20:00
        type: string
      workstageid:
        example: 3
        type: integer
    type: object
  handlers.ProjectnoteGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.ProjectNoteResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuoteGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.QuoteResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuoteItemGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.QuoteItemResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuoteItemListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.QuoteItemResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuoteItemResponse:
    properties:
      activeworkstageid:
        description: Status & scheduling
        type: integer
      activeworkstate:
        type: string
      billAmount:
        description: BillAmount is calculated based on BillType config
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item rates and quantities, 2 = fixed fee, 3 = unit prices,
          4 = item rates, 5 = hours spent and quantities, 8 = hours spent
        type: integer
      billable:
        type: boolean
      budget:
        description: Budget is calculated based on BudgetType config
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals, 3 = unit prices, 4 = item rates'
        type: integer
      categoryid:
        type: integer
      chargeRateType:
        description: |-
          ChargeRateType determines how output costs are calculated:
          1 (Single Rate) = use outLabourPrice; 2 (Split Rate) = use outLabourPrice of linked hourly rate services; 0 = no charge rate tracking
        type: string
      code:
        type: string
      completedate:
        type: string
      contactid:
        items:
          type: integer
        type: array
      costRateType:
        description: |-
          CostRateType determines how input costs are calculated:
          1 (Staff Rate) = use rate of linked staff members; 2 (Service Rate) = use rate of linked hourly rate services; 0 = no cost rate tracking
        type: string
      createdatetime:
        type: string
      creatorid:
        type: integer
      deleted:
        type: boolean
      discount:
        type: number
      discountRate:
        type: number
      duedate:
        type: string
      effortScoreId:
        type: integer
      estGrossMargin:
        description: EstGrossMargin = estProfit / estBillAmount % (to nearest whole
          number)
        type: number
      estInLabour:
        description: EstInLabour is the estimated input labour amount ($); sum of
          estInLabour for all non-deleted timeallocations
        type: number
      estInTotal:
        description: EstInTotal is the estimated input/cost total = estInLabour +
          outUnitTotal
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        description: EstOutLabour is the estimated output labour amount ($); sum of
          estOutLabour for all non-deleted timeallocations
        type: number
      estProfit:
        description: EstProfit = estBillAmount - estInTotal = (estOutLabour + outUnitTotal)
          - (estInLabour + outUnitTotal)
        type: number
      hourlyrateserviceid:
        type: integer
      id:
        description: Core identity
        type: integer
      impactScoreId:
        type: integer
      importanceScoreId:
        type: integer
      inAccountingCodeId:
        type: integer
      inLabourPrice:
        description: InLabourPrice is the internal (cost) price of labour for this
          item
        type: number
      inTaxCodeId:
        description: Tax & accounting
        type: integer
      inTaxRate:
        type: number
      inUnitId:
        description: Units
        type: integer
      inUnitPrice:
        description: Sensitive financial fields — pointer types required for NilSensitiveFields
        type: number
      inUnitQty:
        type: number
      inUnitTotal:
        description: InUnitTotal is the input unit line total = inUnitPrice * inUnitQty
        type: number
      isDiscountPercent:
        type: boolean
      itemcollectionid:
        type: integer
      itemtypeid:
        type: integer
      lastmodifiedutc:
        type: string
      manualBillAmount:
        type: number
      manualBudget:
        type: number
      name:
        description: Basic info
        type: string
      outAccountingCodeId:
        type: integer
      outLabourPrice:
        description: OutLabourPrice is the sale price for labour
        type: number
      outLabourPriceMultiplier:
        type: number
      outTaxCodeId:
        type: integer
      outTaxRate:
        type: number
      outUnitId:
        type: integer
      outUnitPrice:
        type: number
      outUnitPriceMultiplier:
        type: number
      outUnitQty:
        type: number
      outUnitTotal:
        description: OutUnitTotal is the output unit line total = outUnitPrice * outUnitQty
        type: number
      parentid:
        type: integer
      priorityid:
        type: integer
      productid:
        type: integer
      projectedProfit:
        description: ProjectedProfit = estBillAmount - projectedInTotal (difference
          between expected total revenue and projected costs)
        type: number
      quoteid:
        description: Relationships
        type: integer
      startdate:
        type: string
      storyPoints:
        description: Scoring
        type: number
      tagid:
        items:
          type: integer
        type: array
      timeBillable:
        type: number
      timeallocated:
        description: Time
        type: number
      timespent:
        type: number
      trackingOptionId:
        items:
          type: integer
        type: array
      uniquetoken:
        type: string
      updatedAt:
        type: number
      urgencyScoreId:
        type: integer
    type: object
  handlers.QuoteListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.QuoteResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuotePhaseGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.QuotePhaseResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuotePhaseListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.QuotePhaseResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuotePhaseResponse:
    properties:
      billAmount:
        description: BillAmount is calculated based on BillType config
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item rates and quantities, 2 = fixed fee, 3 = unit prices,
          4 = item rates, 5 = hours spent and quantities, 8 = hours spent
        type: integer
      budget:
        description: Budget is calculated based on BudgetType config
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals, 3 = unit prices, 4 = item rates'
        type: integer
      datecreated:
        example: 2024-01-10T09:00:00
        type: string
      deleted:
        example: false
        type: boolean
      discount:
        type: number
      duedate:
        example: 2024-02-15T00:00:00
        type: string
      estGrossMargin:
        description: EstGrossMargin = estProfit / estBillAmount % (to nearest whole
          number)
        type: number
      estInLabour:
        description: EstInLabour is the estimated input labour amount ($); sum of
          estInLabour for all non-deleted timeallocations
        type: number
      estInTotal:
        description: EstInTotal is the estimated input/cost total = estInLabour +
          outUnitTotal
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        description: EstOutLabour is the estimated output labour amount ($); sum of
          estOutLabour for all non-deleted timeallocations
        type: number
      estProfit:
        description: EstProfit = estBillAmount - estInTotal = (estOutLabour + outUnitTotal)
          - (estInLabour + outUnitTotal)
        type: number
      id:
        description: Core identity
        example: 5
        type: integer
      inUnitTotal:
        description: InUnitTotal is the input unit line total = inUnitPrice * inUnitQty
        type: number
      itemsActive:
        example: 2
        type: integer
      itemsCompleted:
        example: 3
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        description: Basic info
        example: Phase 1
        type: string
      outUnitTotal:
        description: OutUnitTotal is the output unit line total = outUnitPrice * outUnitQty
        type: number
      parentid:
        example: 0
        type: integer
      projectedInLabour:
        type: number
      projectedInTotal:
        type: number
      projectedProfit:
        description: ProjectedProfit = estBillAmount - projectedInTotal (difference
          between expected total revenue and projected costs)
        type: number
      quoteid:
        description: Relationships
        example: 20
        type: integer
      startdate:
        example: 2024-01-15T00:00:00
        type: string
      storyPoints:
        description: Progress (non-sensitive)
        example: 13
        type: number
      timeBillable:
        description: Sensitive financial fields — pointer types required for NilSensitiveFields
        type: number
      timeallocated:
        type: number
    type: object
  handlers.QuoteResponse:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      activeworkstate:
        description: Status
        example: pending
        type: string
      address1:
        description: Address
        example: 123 Main Street
        type: string
      address2:
        example: Suite 100
        type: string
      address3:
        type: string
      approveddate:
        example: 2024-01-20T00:00:00
        type: string
      billAmount:
        description: Bill detail (sensitive; field group "billamount")
        example: 5000
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        example: 5750
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item totals, 2 = fixed fee, 3 = unit prices,
          4 = item labour values, 5 = time spent, 6 = fixed amount per phase,
          7 = fixed amount per project, 8 = item labour values (tracked time only)
        example: 1
        type: integer
      budget:
        description: Budget detail (sensitive; field group "budget")
        example: 5000
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        example: 5750
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals'
        example: 1
        type: integer
      city:
        example: New York
        type: string
      clientcontactname:
        description: Client contact
        example: John Doe
        type: string
      companyid:
        description: Company
        example: 5
        type: integer
      companyname:
        example: Acme Corp
        type: string
      country:
        example: United States
        type: string
      customfieldname:
        description: Custom field (requires QuoteDetails JOIN)
        example: Reference
        type: string
      customfieldvalue:
        example: REF-001
        type: string
      description:
        example: Quote for website design services
        type: string
      emaileddate:
        example: 2024-01-15T13:20:00
        type: string
      emailedto:
        example: client@example.com
        type: string
      emailedtoclient:
        description: Flags
        example: true
        type: boolean
      grandtotal:
        example: 5750
        type: number
      id:
        example: 20
        type: integer
      lastmodifiedutc:
        description: Audit
        example: 2024-01-18T13:20:00
        type: string
      number:
        description: Core
        example: QT-001
        type: string
      pagetitle:
        description: Display
        example: Quote
        type: string
      phases:
        description: |-
          Sub-entities — populated only when IncludePhases=true (via OUTER APPLY in main query).
          Use fields=phases or fields=all,phases to include. Never triggered by "all" alone.
        items:
          $ref: '#/definitions/handlers.QuoteSubPhaseItem'
        type: array
      projectid:
        description: Project
        example: 15
        type: integer
      quotedate:
        description: Dates
        example: 2024-01-15T00:00:00
        type: string
      quotedby:
        description: Quoted by (contact name)
        example: Jane Doe
        type: string
      showcostbreakdown:
        example: false
        type: boolean
      showitemdescription:
        example: true
        type: boolean
      showphases:
        example: true
        type: boolean
      state:
        example: NY
        type: string
      subtotal:
        description: Financial totals (sensitive; field group "totals")
        example: 5000
        type: number
      taxable:
        description: Tax (require Quotes / QuoteDetails JOINs)
        example: true
        type: boolean
      taxrate:
        example: 15
        type: number
      taxtotal:
        example: 750
        type: number
      title:
        example: Website Project Quote
        type: string
      type:
        description: Type and description (require Quotes JOIN)
        example: quote
        type: string
      validdate:
        example: 2024-02-15T00:00:00
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.QuoteSubItemItem:
    properties:
      activeworkstate:
        example: active
        type: string
      billAmount:
        example: 1000
        type: number
      billAmountTax:
        example: 1150
        type: number
      billType:
        example: 1
        type: integer
      billable:
        example: true
        type: boolean
      budget:
        example: 1000
        type: number
      budgetTax:
        example: 1150
        type: number
      budgetType:
        example: 1
        type: integer
      categoryid:
        example: 3
        type: integer
      code:
        example: ITEM-001
        type: string
      contactid:
        example:
        - 10
        items:
          type: integer
        type: array
      deleted:
        example: false
        type: boolean
      discount:
        example: 0
        type: number
      estInTotal:
        example: 500
        type: number
      estInTotalTax:
        example: 575
        type: number
      id:
        example: 1
        type: integer
      inUnitTotal:
        example: 500
        type: number
      itemcollectionid:
        example: 5
        type: integer
      itemtypeid:
        example: 1
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Web Design
        type: string
      outUnitTotal:
        example: 1000
        type: number
      parentid:
        example: 0
        type: integer
      quoteid:
        example: 20
        type: integer
      sortorder:
        example: "0x000001"
        type: string
      timeBillable:
        example: 120
        type: integer
      timeallocated:
        example: 120
        type: integer
      trackingOptionId:
        example: "0"
        type: string
    type: object
  handlers.QuoteSubPhaseItem:
    properties:
      billAmount:
        example: 5000
        type: number
      billAmountTax:
        example: 5750
        type: number
      billType:
        example: 1
        type: integer
      budget:
        example: 5000
        type: number
      budgetTax:
        example: 5750
        type: number
      budgetType:
        example: 1
        type: integer
      deleted:
        example: false
        type: boolean
      discount:
        example: 0
        type: number
      estGrossMargin:
        example: 60
        type: number
      estInLabour:
        example: 2000
        type: number
      estInTotal:
        example: 2000
        type: number
      estInTotalTax:
        example: 2300
        type: number
      estOutLabour:
        example: 5000
        type: number
      estProfit:
        example: 3000
        type: number
      id:
        example: 5
        type: integer
      inUnitTotal:
        example: 2000
        type: number
      items:
        items:
          $ref: '#/definitions/handlers.QuoteSubItemItem'
        type: array
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Phase 1
        type: string
      outUnitTotal:
        example: 5000
        type: number
      parentid:
        example: 0
        type: integer
      projectedInLabour:
        example: 2000
        type: number
      projectedInTotal:
        example: 2000
        type: number
      projectedProfit:
        example: 3000
        type: number
      quoteid:
        example: 20
        type: integer
      sortorder:
        example: "0x000001"
        type: string
      timeBillable:
        example: 480
        type: integer
      timeallocated:
        example: 480
        type: integer
    type: object
  handlers.QuoteTemplateListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.QuoteTemplateResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuoteTemplateResponse:
    properties:
      id:
        type: integer
      title:
        example: Website Quote Template
        type: string
    type: object
  handlers.QuoteWorkStageHistoryListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.QuoteWorkStageHistoryResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.QuoteWorkStageHistoryResponse:
    properties:
      contactid:
        example: 10
        type: integer
      deleted:
        example: false
        type: boolean
      id:
        example: 1
        type: integer
      name:
        example: Approved
        type: string
      quoteid:
        example: 20
        type: integer
      setdatetime:
        example: 2024-01-18T13:20:00
        type: string
      workstageid:
        example: 3
        type: integer
    type: object
  handlers.RemoveAllContactsFromItemsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.RemoveAllTagsFromItemsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.RemoveAllTagsFromProjectsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.RemoveContactsFromProjectsPayload:
    properties:
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.RemoveContactsFromRolesPayload:
    properties:
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.RemoveTagsFromCompaniesPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.RemoveTagsFromContactsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.RemoveTagsFromProjectsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.ResthookListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ResthookResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ResthookRequestListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ResthookRequestResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ResthookRequestResponse:
    properties:
      completetime:
        example: 2024-01-18T13:20:01
        type: string
      dataid:
        example: 100
        type: integer
      dataurl:
        example: https://api.example.com/data/100
        type: string
      event:
        example: project
        type: string
      httpstatuscode:
        example: 200
        type: integer
      id:
        type: integer
      nextruntime:
        example: 2024-01-18T13:20:00
        type: string
      resthookid:
        example: 2
        type: integer
      starttime:
        example: 2024-01-18T13:20:00
        type: string
      tries:
        example: 1
        type: integer
      url:
        example: https://example.com/webhook
        type: string
    type: object
  handlers.ResthookResponse:
    properties:
      event:
        example: project
        type: string
      id:
        type: integer
      url:
        example: https://example.com/webhook
        type: string
    type: object
  handlers.RoleGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.RoleResponse'
      status:
        example: success
        type: string
    type: object
  handlers.RoleListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.RoleResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.RoleResponse:
    properties:
      color:
        example: '#1A5276'
        type: string
      contactid:
        items:
          type: integer
        type: array
      id:
        example: 1
        type: integer
      name:
        example: Administrator
        type: string
    type: object
  handlers.RolesToContactsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      roleid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.ServiceRateListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.ServiceRateResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.ServiceRateResponse:
    properties:
      billable:
        example: true
        type: boolean
      description:
        example: Standard hourly rate
        type: string
      id:
        type: integer
      inAccountingCodeId:
        example: 3
        type: integer
      inTaxCodeId:
        example: 1
        type: integer
      name:
        example: Standard Rate
        type: string
      outAccountingCodeId:
        example: 4
        type: integer
      outTaxCodeId:
        example: 2
        type: integer
      sortorder:
        example: "1"
        type: string
      taxable:
        example: true
        type: boolean
    type: object
  handlers.SetRolePermissionInput:
    properties:
      add:
        example: true
        type: boolean
      delete:
        example: false
        type: boolean
      edit:
        example: true
        type: boolean
      permissionid:
        example: 8
        type: integer
      view:
        example: true
        type: boolean
    type: object
  handlers.SettingsInvoicesAutonumberingListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.SettingsInvoicesAutonumberingResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.SettingsInvoicesAutonumberingResponse:
    properties:
      autoinvoicenumber:
        example: "true"
        type: string
      id:
        example: 1
        type: integer
      invoicenumbercount:
        example: 42
        type: integer
      invoicenumbermask:
        example: INV-####
        type: string
      invoicenumberplaceholder:
        example: '####'
        type: string
    type: object
  handlers.SettingsProductFixedpriceListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.SettingsProductFixedpriceResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.SettingsProductFixedpriceResponse:
    properties:
      billable:
        example: true
        type: boolean
      code:
        example: WEB-PKG
        type: string
      color:
        example: '#1A5276'
        type: string
      divisionid:
        example: 1
        type: integer
      id:
        example: 1
        type: integer
      inAccountingCodeId:
        example: 0
        type: integer
      inTaxCodeId:
        example: 1
        type: integer
      inUnitId:
        example: 1
        type: integer
      inUnitPrice:
        example: 500
        type: number
      itemtypeid:
        example: 3
        type: integer
      name:
        example: Website Package
        type: string
      outAccountingCodeId:
        example: 0
        type: integer
      outTaxCodeId:
        example: 1
        type: integer
      outUnitId:
        example: 1
        type: integer
      outUnitPrice:
        example: 1500
        type: number
      purchasedescription:
        example: Website design and development services
        type: string
      saledescription:
        example: Complete website design and development
        type: string
    type: object
  handlers.SettingsProductGoodserviceListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.SettingsProductGoodserviceResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.SettingsProductGoodserviceResponse:
    properties:
      billable:
        example: true
        type: boolean
      code:
        example: DESIGN-SVC
        type: string
      color:
        example: '#1A5276'
        type: string
      divisionid:
        example: 1
        type: integer
      hourlyrateserviceid:
        example: 3
        type: integer
      hourlyrateservicename:
        example: Senior Designer
        type: string
      id:
        example: 1
        type: integer
      inAccountingCodeId:
        example: 0
        type: integer
      inLabourPrice:
        example: 50
        type: number
      inTaxCodeId:
        example: 1
        type: integer
      inUnitId:
        example: 1
        type: integer
      inUnitPrice:
        example: 50
        type: number
      itemtypeid:
        example: 2
        type: integer
      name:
        example: Design Service
        type: string
      outAccountingCodeId:
        example: 0
        type: integer
      outLabourPrice:
        example: 100
        type: number
      outTaxCodeId:
        example: 1
        type: integer
      outUnitId:
        example: 1
        type: integer
      outUnitPrice:
        example: 100
        type: number
      purchasedescription:
        example: Design work
        type: string
      saledescription:
        example: Professional design services
        type: string
    type: object
  handlers.SettingsProductHourlyserviceListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.SettingsProductHourlyserviceResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.SettingsProductHourlyserviceResponse:
    properties:
      billable:
        example: true
        type: boolean
      code:
        example: SR-DESIGN
        type: string
      color:
        example: '#1A5276'
        type: string
      divisionid:
        example: 1
        type: integer
      hourlyrateserviceid:
        example: 3
        type: integer
      hourlyrateservicename:
        example: Senior Designer
        type: string
      id:
        example: 1
        type: integer
      inAccountingCodeId:
        example: 0
        type: integer
      inLabourPrice:
        example: 50
        type: number
      inTaxCodeId:
        example: 1
        type: integer
      itemtypeid:
        example: 1
        type: integer
      name:
        example: Senior Designer
        type: string
      outAccountingCodeId:
        example: 0
        type: integer
      outLabourPrice:
        example: 100
        type: number
      outTaxCodeId:
        example: 1
        type: integer
      purchasedescription:
        example: Design hours
        type: string
      saledescription:
        example: Hourly design services
        type: string
    type: object
  handlers.SettingsProjectsAutonumberingListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.SettingsProjectsAutonumberingResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.SettingsProjectsAutonumberingResponse:
    properties:
      autoprojectnumber:
        example: "true"
        type: string
      id:
        example: 1
        type: integer
      projectnumbercount:
        example: 100
        type: integer
      projectnumbermask:
        example: PRJ-####
        type: string
      projectnumberplaceholder:
        example: '####'
        type: string
      projectnumbertype:
        example: sequential
        type: string
    type: object
  handlers.SettingsProjectsListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.SettingsProjectsResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.SettingsProjectsResponse:
    properties:
      autoprojectnumber:
        example: "true"
        type: string
      emptyprojectcategory:
        example: Uncategorized
        type: string
      emptytaskcategory:
        example: General
        type: string
      enableSubPhases:
        example: false
        type: boolean
      id:
        example: 1
        type: integer
      projectnumbercount:
        example: 100
        type: integer
      projectnumbermask:
        example: PRJ-####
        type: string
      projectnumberplaceholder:
        example: '####'
        type: string
      projectnumbertype:
        example: sequential
        type: string
      projectvariable:
        example: Project
        type: string
      taskordering:
        example: manual
        type: string
    type: object
  handlers.SettingsQuotesAutonumberingListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.SettingsQuotesAutonumberingResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.SettingsQuotesAutonumberingResponse:
    properties:
      autoquotenumber:
        example: "true"
        type: string
      id:
        example: 1
        type: integer
      quotenumbercount:
        example: 20
        type: integer
      quotenumbermask:
        example: QT-####
        type: string
      quotenumberplaceholder:
        example: '####'
        type: string
    type: object
  handlers.SettingsQuotesListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.SettingsQuotesResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.SettingsQuotesResponse:
    properties:
      clientemailcontent:
        example: Please find your quote attached.
        type: string
      clientemailfromaddress:
        example: noreply@example.com
        type: string
      clientemailsubject:
        example: Your Quote from ProWorkflow
        type: string
      contactfooter:
        example: Thank you for your business
        type: string
      footerdetails:
        example: Payment due within 30 days
        type: string
      id:
        example: 1
        type: integer
      logo:
        example: https://example.com/img/logo.png
        type: string
      pagetitle:
        example: Quote
        type: string
      quoteperiod:
        example: 30
        type: integer
      quoteterms:
        example: Valid for 30 days
        type: string
      showItemDescription:
        example: true
        type: boolean
      showPhases:
        example: true
        type: boolean
      showcostbreakdown:
        example: false
        type: boolean
      usequoteterms:
        example: "true"
        type: string
    type: object
  handlers.StaffRateListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.StaffRateResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.StaffRateResponse:
    properties:
      firstname:
        example: Jane
        type: string
      hourlyrateserviceid:
        example: 2
        type: integer
      hourlyrateservicename:
        example: Standard Rate
        type: string
      id:
        type: integer
      lastname:
        example: Smith
        type: string
      outprice:
        example: 120
        type: number
    type: object
  handlers.StartTimerRequest:
    properties:
      itemid:
        example: 2150
        type: integer
    type: object
  handlers.StopTimerRequest:
    properties:
      notes:
        example: Worked on homepage
        type: string
      timespent:
        example: 60
        type: integer
    type: object
  handlers.TagsToCompaniesPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.TagsToContactsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.TagsToItemsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.TagsToProjectsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.TeamGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.TeamResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TeamListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.TeamResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TeamResponse:
    properties:
      code:
        example: ENG
        type: string
      groupid:
        items:
          type: integer
        type: array
      id:
        example: 1
        type: integer
      name:
        example: Engineering
        type: string
    type: object
  handlers.TemplateItemGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.TemplateItemResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TemplateItemListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.TemplateItemResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TemplateItemResponse:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      activeworkstate:
        example: active
        type: string
      billAmount:
        description: BillAmount is calculated based on BillType config
        type: number
      billAmountTax:
        description: BillAmountTax is the tax on BillAmount, calculated based on BillType
          config
        type: number
      billType:
        description: |-
          BillType determines how billAmount is calculated:
          0 = no bill amount, 1 = item rates and quantities, 2 = fixed fee, 3 = unit prices,
          4 = item rates, 5 = hours spent and quantities, 8 = hours spent
        type: integer
      billable:
        example: true
        type: boolean
      budget:
        description: Budget is calculated based on BudgetType config
        type: number
      budgetTax:
        description: BudgetTax is the tax on Budget, calculated based on BudgetType
          config
        type: number
      budgetType:
        description: 'BudgetType determines how budget is calculated: 0 = no budget,
          1 = item totals, 3 = unit prices, 4 = item rates'
        type: integer
      categoryid:
        example: 3
        type: integer
      chargeRateType:
        description: |-
          ChargeRateType determines how output costs are calculated:
          1 (Single Rate) = use outLabourPrice; 2 (Split Rate) = use outLabourPrice of linked hourly rate services; 0 = no charge rate tracking
        type: integer
      code:
        example: TASK-001
        type: string
      completedate:
        example: 2024-01-19T00:00:00
        type: string
      contactid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      costRateType:
        description: |-
          CostRateType determines how input costs are calculated:
          1 (Staff Rate) = use rate of linked staff members; 2 (Service Rate) = use rate of linked hourly rate services; 0 = no cost rate tracking
        type: integer
      createdatetime:
        example: 2024-01-10T09:00:00
        type: string
      creatorid:
        example: 10
        type: integer
      deleted:
        example: false
        type: boolean
      dependenttaskid:
        example: ""
        type: string
      discount:
        description: Discount (sensitive)
        type: number
      discountRate:
        type: number
      duedate:
        example: 2024-01-20T00:00:00
        type: string
      effortScoreId:
        type: integer
      estGrossMargin:
        description: EstGrossMargin = estProfit / estBillAmount % (to nearest whole
          number)
        type: number
      estInLabour:
        description: |-
          Estimated (sensitive)
          EstInLabour is the estimated input labour amount ($); sum of estInLabour for all non-deleted timeallocations
        type: number
      estInTotal:
        description: EstInTotal is the estimated input/cost total = estInLabour +
          outUnitTotal
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        description: EstOutLabour is the estimated output labour amount ($); sum of
          estOutLabour for all non-deleted timeallocations
        type: number
      estProfit:
        description: |-
          Profit (sensitive)
          EstProfit = estBillAmount - estInTotal = (estOutLabour + outUnitTotal) - (estInLabour + outUnitTotal)
        type: number
      hourlyrateserviceid:
        example: 0
        type: integer
      id:
        example: 1
        type: integer
      impactScoreId:
        type: integer
      importanceScoreId:
        type: integer
      inAccountingCodeId:
        type: integer
      inLabourPrice:
        description: InLabourPrice is the internal (cost) price of labour for this
          item
        type: number
      inTaxCodeId:
        description: Tax/accounting
        type: integer
      inTaxRate:
        type: number
      inUnitId:
        description: Units/pricing (sensitive)
        type: integer
      inUnitPrice:
        type: number
      inUnitQty:
        type: number
      inUnitTotal:
        description: InUnitTotal is the input unit line total = inUnitPrice * inUnitQty
        type: number
      isDiscountPercent:
        type: boolean
      itemcollectionid:
        example: 5
        type: integer
      itemcollectiontemplateid:
        example: 2
        type: integer
      itemtypeid:
        example: 1
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      manualBillAmount:
        description: Billing (sensitive)
        type: number
      manualBudget:
        description: Budget (sensitive)
        type: number
      name:
        example: Design homepage
        type: string
      outAccountingCodeId:
        type: integer
      outLabourPrice:
        description: OutLabourPrice is the sale price for labour
        type: number
      outLabourPriceMultiplier:
        type: number
      outTaxCodeId:
        type: integer
      outTaxRate:
        type: number
      outUnitId:
        type: integer
      outUnitPrice:
        type: number
      outUnitPriceMultiplier:
        type: number
      outUnitQty:
        type: number
      outUnitTotal:
        description: OutUnitTotal is the output unit line total = outUnitPrice * outUnitQty
        type: number
      parentid:
        example: 0
        type: integer
      prerequisiteid:
        example: ""
        type: string
      priorityid:
        example: 2
        type: integer
      productid:
        example: 0
        type: integer
      projectedProfit:
        description: ProjectedProfit = estBillAmount - projectedInTotal (difference
          between expected total revenue and projected costs)
        type: number
      sortorder:
        example: "0x000001"
        type: string
      startdate:
        example: 2024-01-15T00:00:00
        type: string
      storyPoints:
        description: Scoring
        type: number
      tagid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      timeBillable:
        example: 120
        type: number
      timeallocated:
        example: 120
        type: number
      timespent:
        example: 60
        type: number
      trackingOptionId:
        type: string
      uniquetoken:
        example: abc123xyz
        type: string
      urgencyScoreId:
        type: integer
    type: object
  handlers.TemplatePhaseCreatePayload:
    properties:
      name:
        example: Design Phase
        type: string
      parentid:
        example: 0
        type: integer
      templateid:
        example: 2
        type: integer
    type: object
  handlers.TemplatePhaseGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.TemplatePhaseResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TemplatePhaseListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.TemplatePhaseResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TemplatePhaseResponse:
    properties:
      billAmount:
        type: number
      billAmountTax:
        type: number
      billType:
        description: Billing (sensitive)
        type: integer
      budget:
        type: number
      budgetTax:
        type: number
      budgetType:
        description: Budget (sensitive)
        type: integer
      datecreated:
        example: 2024-01-10T09:00:00
        type: string
      deleted:
        example: false
        type: boolean
      discount:
        type: number
      duedate:
        example: 2024-02-15T00:00:00
        type: string
      estGrossMargin:
        type: number
      estInLabour:
        description: Estimated (sensitive)
        type: number
      estInTotal:
        type: number
      estInTotalTax:
        type: number
      estOutLabour:
        type: number
      estProfit:
        description: Profit/margin (sensitive)
        type: number
      id:
        example: 5
        type: integer
      inUnitTotal:
        description: Units
        type: number
      itemcollectiontemplateid:
        example: 2
        type: integer
      itemsActive:
        example: 2
        type: integer
      itemsCompleted:
        example: 3
        type: integer
      lastmodifiedutc:
        example: 2024-01-18T13:20:00
        type: string
      name:
        example: Design Phase
        type: string
      outUnitTotal:
        type: number
      parentid:
        example: 0
        type: integer
      projectedProfit:
        type: number
      startdate:
        example: 2024-01-15T00:00:00
        type: string
      storyPoints:
        description: Aggregated fields
        example: 13
        type: number
      timeBillable:
        type: number
      timeallocated:
        type: number
      timespent:
        type: number
    type: object
  handlers.TemplatePhaseUpdatePayload:
    properties:
      name:
        example: Design Phase
        type: string
      parentid:
        example: 0
        type: integer
      sortorder:
        example: 1
        type: integer
    type: object
  handlers.TimeAllocationCreatePayload:
    properties:
      contactid:
        example: 10
        type: integer
      hourlyrateserviceid:
        example: 0
        type: integer
      itemid:
        example: 5
        type: integer
      starttime:
        example: "2024-01-15T09:00:00Z"
        type: string
      timeBillable:
        example: 120
        type: integer
      timeallocated:
        example: 120
        type: integer
    type: object
  handlers.TimeAllocationDeletePayload:
    properties:
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.TimeAllocationGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.TimeAllocationResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TimeAllocationListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.TimeAllocationResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TimeAllocationResponse:
    properties:
      contactid:
        example: 10
        type: integer
      estinlabour:
        description: EstInLabour is the estimated total internal labour cost ($) =
          inLabourPrice * timeAllocated / 60
        example: 100
        type: number
      estoutlabour:
        description: EstOutLabour is the estimated total sale labour cost ($) = outLabourPrice
          * timeAllocated / 60
        example: 200
        type: number
      hourlyrateserviceid:
        example: 0
        type: integer
      id:
        example: 1
        type: integer
      inlabourprice:
        description: |-
          InLabourPrice is the internal labour rate ($/hr), calculated based on the linked item's costRateType:
          - costRateType 1 (staff rate): contact.payrate * contact.payRateMultiplier, or division.defaultpayrate * division.payratemultiplier if contact.payrate is null
          - costRateType 2 (service rate): inLabourPrice ?? hourlyrateservice.inLabourPrice
          - otherwise: 0
        example: 50
        type: number
      itemid:
        example: 5
        type: integer
      outlabourprice:
        description: |-
          OutLabourPrice is the sale labour rate ($/hr), calculated based on the linked item's chargeRateType:
          - chargeRateType 1 (single rate): item.outLabourPrice
          - chargeRateType 2 (split rate): outLabourPrice ?? hourlyrateservice.outLabourPrice
          - otherwise: 0
        example: 100
        type: number
      projectid:
        example: 15
        type: integer
      starttime:
        example: 2024-01-15T09:00:00
        type: string
      timeallocated:
        example: 120
        type: integer
      timebillable:
        example: 120
        type: integer
    type: object
  handlers.TimeAllocationUpdatePayload:
    properties:
      contactid:
        type: integer
      hourlyrateserviceid:
        type: integer
      itemid:
        type: integer
      starttime:
        type: string
      timeBillable:
        type: integer
      timeallocated:
        type: integer
    type: object
  handlers.TimeCreatePayload:
    properties:
      contactid:
        example: 1
        type: integer
      itemid:
        example: 73675
        type: integer
      notes:
        example: my note
        type: string
      starttime:
        example: "2026-04-21T23:41:44.870Z"
        type: string
      timeAllocationId:
        example: 0
        type: integer
      timespent:
        example: 240
        type: integer
    type: object
  handlers.TimeGetResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.TimeResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TimeListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.TimeResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.TimeResponse:
    properties:
      accountedfor:
        example: false
        type: boolean
      billable:
        example: true
        type: boolean
      companyid:
        example: 2
        type: integer
      companyname:
        example: Acme Corp
        type: string
      contactid:
        example: 5
        type: integer
      contactname:
        example: John Doe
        type: string
      endtime:
        example: 2024-01-15T17:00:00
        type: string
      id:
        example: 1
        type: integer
      itemcollectionid:
        example: 5
        type: integer
      itemid:
        example: 10
        type: integer
      itemname:
        example: Design Homepage
        type: string
      lastmodifiedutc:
        example: 2024-01-15T15:30:00
        type: string
      notes:
        example: Worked on homepage design
        type: string
      projectid:
        example: 3
        type: integer
      projectnumber:
        example: PRJ-001
        type: string
      projecttitle:
        example: Website Redesign
        type: string
      startdate:
        example: "2024-01-15"
        type: string
      starttime:
        example: 2024-01-15T09:00:00
        type: string
      timeallocationid:
        example: 1
        type: integer
      timespent:
        example: 480
        type: number
    type: object
  handlers.TimeUpdatePayload:
    properties:
      itemid:
        example: 73675
        type: integer
      notes:
        example: updated note
        type: string
      starttime:
        example: "2026-04-21T23:41:44.870Z"
        type: string
      timespent:
        example: 240
        type: integer
    type: object
  handlers.TrackingOptionsToItemsPayload:
    properties:
      id:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      trackingOptionId:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.UpdateCompanyPayload:
    properties:
      avatarname:
        example: avatar.jpg
        type: string
      categoryid:
        description: Additional fields
        example: 1
        type: integer
      code:
        example: ABC
        type: string
      creatorid:
        example: 1
        type: integer
      email:
        example: info@abc.com
        type: string
      facebook:
        description: Social media
        example: https://facebook.com/abc
        type: string
      fax:
        example: 123-456-7891
        type: string
      isperson:
        type: boolean
      linkedin:
        example: https://linkedin.com/company/abc
        type: string
      maincompanylocationid:
        example: 1
        type: integer
      maincontactid:
        example: 1
        type: integer
      name:
        description: Basic fields
        example: ABC Corporation
        type: string
      phone:
        description: Contact information
        example: 123-456-7890
        type: string
      tagid:
        description: Tags
        example: 1,2,3
        type: string
      twitter:
        example: '@abccorp'
        type: string
      type:
        enum:
        - client
        - contractor
        - staff
        - other
        example: client
        type: string
      website:
        example: https://www.abc.com
        type: string
    type: object
  handlers.UpdateContactGroupsPayload:
    properties:
      groupid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.UpdateContactNotePayload:
    properties:
      note:
        example: Updated note about the contact
        type: string
    type: object
  handlers.UpdateContactPayload:
    properties:
      address1:
        description: Address
        example: 123 Main St
        type: string
      address2:
        example: Suite 100
        type: string
      address3:
        example: ""
        type: string
      allowlogin:
        description: Login/Access
        example: true
        type: boolean
      city:
        example: New York
        type: string
      companyFavouriteId:
        description: Favorites
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      companyid:
        description: Company/Organization
        example: 1
        type: integer
      country:
        example: USA
        type: string
      defaulthourlyrateid:
        description: Additional
        example: 1
        type: integer
      divisionid:
        example: 1
        type: integer
      email:
        example: john@example.com
        type: string
      emailsignature:
        description: Settings
        example: <p>Best regards,<br>John</p>
        type: string
      firstname:
        description: Basic information
        example: John
        type: string
      groupid:
        description: Alias
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      groupids:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      ianatimezone:
        example: Pacific/Auckland
        type: string
      itemFavouriteId:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      lastname:
        example: Smith
        type: string
      mobilephone:
        example: 123-456-7891
        type: string
      primarycontact:
        type: boolean
      productFavouriteId:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      projectFavouriteId:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      reportFavouriteId:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      showhistoric:
        type: boolean
      state:
        example: NY
        type: string
      tagid:
        description: Tags
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      title:
        example: CEO
        type: string
      workphone:
        description: Contact information
        example: 123-456-7890
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.UpdateContactTagPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: VIP
        type: string
    type: object
  handlers.UpdateContactTagsPayload:
    properties:
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.UpdateCustomFieldOptionPayload:
    properties:
      displayorder:
        type: integer
      name:
        type: string
    type: object
  handlers.UpdateCustomFieldPayload:
    properties:
      displayorder:
        type: integer
      isActive:
        type: boolean
      name:
        type: string
      staffonly:
        type: boolean
    type: object
  handlers.UpdateDivisionPayload:
    properties:
      chargeRateType:
        example: hourly
        type: string
      costRateType:
        example: hourly
        type: string
      currencyid:
        example: 1
        type: integer
      defaultpayrate:
        example: 50
        type: number
      ianatimezone:
        example: "0"
        type: string
      name:
        example: Engineering Division
        type: string
      payratemultiplier:
        example: 1.5
        type: number
    type: object
  handlers.UpdateFolderPayload:
    properties:
      contactid:
        items:
          type: integer
        type: array
      description:
        example: Assets for client review
        type: string
      name:
        example: Client Assets
        type: string
      public:
        example: false
        type: boolean
      size:
        example: 204800
        type: integer
      taskid:
        example: 5
        type: integer
      type:
        example: custom
        type: string
    type: object
  handlers.UpdateGroupPayload:
    properties:
      contactids:
        example: 1,2,3
        type: string
      name:
        example: Design Team
        type: string
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.UpdateInvoiceItemOrderRequest:
    properties:
      placeafterid:
        example: 123
        type: integer
      placebeforeid:
        example: 456
        type: integer
    type: object
  handlers.UpdateInvoiceOrderRequest:
    properties:
      placeafterid:
        example: 123
        type: integer
      placebeforeid:
        example: 456
        type: integer
    type: object
  handlers.UpdateInvoicePayload:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      address1:
        description: Address fields
        example: 123 Main St
        type: string
      address2:
        example: Suite 100
        type: string
      address3:
        example: ""
        type: string
      autonumber:
        description: Flags
        type: boolean
      city:
        example: New York
        type: string
      clientcompany:
        description: Company/Client info
        example: Acme Corp
        type: string
      clientcontactname:
        example: John Smith
        type: string
      contactfooter:
        example: Contact us at...
        type: string
      country:
        example: USA
        type: string
      customfieldvalue:
        description: Custom fields
        example: REF-001
        type: string
      description:
        example: Updated description
        type: string
      duedate:
        example: "2024-02-15"
        type: string
      footerdetails:
        example: Thank you for your business
        type: string
      invoicedate:
        description: Dates
        example: "2024-01-15"
        type: string
      invoicetermid:
        description: Payment/Financial
        example: 1
        type: integer
      layoutid:
        example: 1
        type: integer
      number:
        example: INV-001
        type: string
      pagesubtitle:
        example: Payment Due
        type: string
      pagetitle:
        description: Layout/Display
        example: Invoice
        type: string
      paymentdetails:
        example: Bank transfer details
        type: string
      paymentperiod:
        example: 30
        type: integer
      paymentterms:
        example: Net 30
        type: string
      purchaseordernumber:
        example: PO-12345
        type: string
      showItemDescription:
        type: boolean
      showPhases:
        type: boolean
      showcostbreakdown:
        type: boolean
      state:
        example: NY
        type: string
      status:
        enum:
        - draft
        - submitted
        - authorised
        - paid
        - voided
        example: submitted
        type: string
      taxable:
        example: true
        type: boolean
      taxrate:
        example: 15
        type: number
      template:
        type: boolean
      title:
        description: Basic fields
        example: Updated Invoice Title
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.UpdateInvoicePhasePayload:
    properties:
      billamount:
        example: 6000
        type: number
      billtype:
        example: 1
        type: integer
      budget:
        example: 5000
        type: number
      budgettype:
        example: 1
        type: integer
      name:
        example: Updated Phase Name
        type: string
    type: object
  handlers.UpdateInvoiceWorkStageRequest:
    properties:
      activeworkstageid:
        example: 9
        type: integer
    type: object
  handlers.UpdateItemCategoryPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Design
        type: string
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.UpdateItemOrderRequest:
    properties:
      placeafterid:
        example: 123
        type: integer
      placebeforeid:
        example: 456
        type: integer
    type: object
  handlers.UpdateItemPayload:
    properties:
      billType:
        example: 1
        type: integer
      budgetType:
        example: 1
        type: integer
      categoryid:
        example: 1
        type: integer
      chargeRateType:
        example: 1
        type: integer
      code:
        example: TASK-001
        type: string
      completedate:
        example: "2024-02-20"
        type: string
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      costRateType:
        example: 1
        type: integer
      description:
        example: Design the homepage layout
        type: string
      duedate:
        example: "2024-02-15"
        type: string
      effortScore:
        example: medium
        type: string
      effortScoreId:
        example: 2
        type: integer
      hourlyrateserviceid:
        example: 1
        type: integer
      impactScore:
        example: high
        type: string
      impactScoreId:
        example: 1
        type: integer
      importanceScore:
        example: high
        type: string
      importanceScoreId:
        example: 1
        type: integer
      inAccountingCodeId:
        example: 1
        type: integer
      inLabourPrice:
        example: 40
        type: number
      inTaxCodeId:
        example: 1
        type: integer
      inUnitId:
        example: 1
        type: integer
      inUnitPrice:
        example: 50
        type: number
      inUnitQty:
        example: 10.5
        type: number
      itemcollectionid:
        example: 5
        type: integer
      itemtypeid:
        example: 1
        type: integer
      manualPercentageComplete:
        example: 75.5
        type: number
      name:
        example: Design Homepage
        type: string
      outAccountingCodeId:
        example: 1
        type: integer
      outLabourPrice:
        example: 60
        type: number
      outLabourPriceMultiplier:
        example: 1.5
        type: number
      outTaxCodeId:
        example: 1
        type: integer
      outUnitId:
        example: 1
        type: integer
      outUnitPrice:
        example: 75
        type: number
      outUnitPriceMultiplier:
        example: 1.5
        type: number
      outUnitQty:
        example: 10.5
        type: number
      parentid:
        example: 2
        type: integer
      prerequisiteid:
        example: 1,2,3
        type: string
      priority:
        example: 3
        type: integer
      priorityid:
        example: 3
        type: integer
      productid:
        example: 4
        type: integer
      projectedTimeManual:
        example: 7200
        type: integer
      projectedTimeSpent:
        example: 3600
        type: integer
      startdate:
        example: "2024-01-15"
        type: string
      status:
        enum:
        - active
        - complete
        example: active
        type: string
      storyPoints:
        example: 5
        type: integer
      tagid:
        example: 1,2
        type: string
      trackingOptionId:
        example: 1,2
        type: string
      urgencyScore:
        example: medium
        type: string
      urgencyScoreId:
        example: 2
        type: integer
    type: object
  handlers.UpdateItemTagPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Urgent
        type: string
    type: object
  handlers.UpdateItemWorkStageRequest:
    properties:
      activeworkstageid:
        example: 9
        type: integer
    type: object
  handlers.UpdateMessagePayload:
    properties:
      notifications:
        example: true
        type: boolean
      public:
        example: false
        type: boolean
    type: object
  handlers.UpdateProjectBookmarkPayload:
    properties:
      title:
        example: Example Site
        type: string
      url:
        example: https://example.com
        type: string
    type: object
  handlers.UpdateProjectCategoryPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Marketing
        type: string
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.UpdateProjectContactsPayload:
    properties:
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.UpdateProjectCustomFieldPayload:
    properties:
      customfieldoptionid:
        description: Option ID for dropdown type fields. Alternatively pass the option
          ID as value.
        example: 5
        type: integer
      type:
        description: Type of the custom field.
        enum:
        - checkbox
        - date
        - dropdown
        - number
        - percentage
        - rating
        - staff
        - text
        example: text
        type: string
      value:
        description: |-
          Value for the custom field. Pass as a string for checkbox ("checked"/"unchecked"),
          date ("YYYY-MM-DD"), rating, and text types. Pass as a number for number, percentage,
          staff (contact ID), and dropdown (customfieldoption ID) types.
        example: some text
        type: string
    type: object
  handlers.UpdateProjectItemPayload:
    properties:
      categoryid:
        example: 1
        type: integer
      code:
        example: TASK-001
        type: string
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      description:
        example: Create homepage design mockups
        type: string
      duedate:
        example: "2024-01-20"
        type: string
      name:
        example: Design homepage
        type: string
      priority:
        example: 2
        type: integer
      startdate:
        example: "2024-01-15"
        type: string
      tagids:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
    type: object
  handlers.UpdateProjectOrderRequest:
    properties:
      placeafterid:
        example: 123
        type: integer
      placebeforeid:
        example: 456
        type: integer
    type: object
  handlers.UpdateProjectPayload:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      categoryid:
        description: Categorization
        example: 1
        type: integer
      chargeRateType:
        example: 1
        type: integer
      clientaccess:
        description: Access settings
        type: boolean
      clientid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      clientviewalltasks:
        type: boolean
      companyid:
        description: Client/Company fields
        example: 5
        type: integer
      completedate:
        example: "2024-04-01"
        type: string
      contactid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      contractorid:
        example:
        - 4
        - 5
        items:
          type: integer
        type: array
      costRateType:
        description: Financial fields
        example: 1
        type: integer
      customfields:
        description: Custom field values to set on update
        items:
          $ref: '#/definitions/handlers.ProjectCustomFieldInput'
        type: array
      customformtitle:
        example: Custom Form
        type: string
      description:
        example: Complete website redesign project
        type: string
      divisionid:
        description: Division/Organization
        example: 1
        type: integer
      duedate:
        example: "2024-03-15"
        type: string
      groupid:
        example: 1
        type: integer
      icalcontactid:
        example:
        - 1
        - 2
        items:
          type: integer
        type: array
      managerid:
        description: Management team
        example: 1
        type: integer
      notification:
        type: boolean
      number:
        example: PRJ-001
        type: string
      priorityid:
        example: 2
        type: integer
      privatenotes:
        description: Additional fields
        example: Internal notes
        type: string
      purchaseorder:
        example: PO-12345
        type: string
      staffid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      staffviewalltasks:
        type: boolean
      startdate:
        description: Date fields
        example: "2024-01-15"
        type: string
      tagid:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
      teamid:
        example: 1
        type: integer
      template:
        type: boolean
      templateused:
        example: 1
        type: integer
      timeallocated:
        example: 3600
        type: integer
      title:
        description: Basic fields
        example: Website Redesign
        type: string
      worktypeid:
        example: 1
        type: integer
    type: object
  handlers.UpdateProjectPhasePayload:
    properties:
      duedate:
        example: "2024-02-15"
        type: string
      name:
        example: Design Phase
        type: string
      parentid:
        example: 0
        type: integer
      startdate:
        example: "2024-01-15"
        type: string
    type: object
  handlers.UpdateProjectSettingsPayload:
    properties:
      clientaccess:
        example: true
        type: boolean
      clientviewalltasks:
        example: false
        type: boolean
      clientviewtime:
        example: false
        type: boolean
      middlecontainerorder:
        example: tasks,phases
        type: string
      notification:
        example: true
        type: boolean
      rightcontainerorder:
        example: messages,files
        type: string
      staffviewalltasks:
        example: true
        type: boolean
    type: object
  handlers.UpdateProjectTagPayload:
    properties:
      color:
        example: A4C0DE
        type: string
      name:
        example: Urgent
        type: string
    type: object
  handlers.UpdateProjectWorkStageRequest:
    properties:
      activeworkstageid:
        example: 9
        type: integer
    type: object
  handlers.UpdateQuoteItemOrderRequest:
    properties:
      placeafterid:
        example: 123
        type: integer
      placebeforeid:
        example: 456
        type: integer
    type: object
  handlers.UpdateQuoteItemPayload:
    properties:
      billamount:
        example: 6000
        type: number
      billtype:
        example: 1
        type: integer
      budget:
        example: 5000
        type: number
      budgettype:
        example: 1
        type: integer
      categoryid:
        example: 2
        type: integer
      duedate:
        example: "2024-01-31"
        type: string
      itemcollectionid:
        example: 456
        type: integer
      itemtypeid:
        example: 1
        type: integer
      name:
        example: Updated Design Work
        type: string
      parentid:
        example: 0
        type: integer
      startdate:
        example: "2024-01-01"
        type: string
      timeallocated:
        example: 40
        type: number
    type: object
  handlers.UpdateQuoteOrderRequest:
    properties:
      placeafterid:
        example: 123
        type: integer
      placebeforeid:
        example: 456
        type: integer
    type: object
  handlers.UpdateQuotePayload:
    properties:
      activeworkstageid:
        example: 1
        type: integer
      address1:
        description: Address fields
        example: 123 Main St
        type: string
      address2:
        example: Suite 100
        type: string
      address3:
        type: string
      approveddate:
        example: "2024-01-20"
        type: string
      city:
        example: New York
        type: string
      clientaccess:
        description: Flags
        type: boolean
      clientcompany:
        example: Acme Corp
        type: string
      clientcontactname:
        example: John Smith
        type: string
      companyid:
        description: Company/Client info
        example: 5
        type: integer
      contactfooter:
        example: Contact us at...
        type: string
      country:
        example: USA
        type: string
      customfieldvalue:
        description: Custom fields
        example: REF-001
        type: string
      description:
        example: Updated description
        type: string
      footerdetails:
        example: Thank you for considering our services
        type: string
      layoutid:
        example: 1
        type: integer
      number:
        example: QUO-001
        type: string
      pagetitle:
        description: Layout/Display
        example: Quote
        type: string
      quotedate:
        description: Dates
        example: "2024-01-15"
        type: string
      quotedby:
        example: Jane Doe
        type: string
      quoteperiod:
        example: 30
        type: integer
      showItemDescription:
        type: boolean
      showPhases:
        type: boolean
      showcostbreakdown:
        type: boolean
      state:
        example: NY
        type: string
      status:
        enum:
        - pending
        - sent
        - accepted
        - declined
        example: sent
        type: string
      taxable:
        example: true
        type: boolean
      taxrate:
        description: Financial
        example: 15
        type: number
      template:
        type: boolean
      terms:
        example: Terms and conditions
        type: string
      title:
        description: Basic fields
        example: Updated Quote Title
        type: string
      validdate:
        example: "2024-02-15"
        type: string
      zerotaxtext:
        example: Tax exempt
        type: string
      zipcode:
        example: "10001"
        type: string
    type: object
  handlers.UpdateQuotePhasePayload:
    properties:
      billamount:
        example: 6000
        type: number
      billtype:
        example: 1
        type: integer
      budget:
        example: 5000
        type: number
      budgettype:
        example: 1
        type: integer
      duedate:
        example: "2024-01-31"
        type: string
      name:
        example: Updated Phase Name
        type: string
      startdate:
        example: "2024-01-01"
        type: string
    type: object
  handlers.UpdateQuoteWorkStageRequest:
    properties:
      activeworkstageid:
        example: 9
        type: integer
    type: object
  handlers.UpdateResthookPayload:
    properties:
      divisionid:
        example: 1
        type: integer
      event:
        enum:
        - newcontact
        - newpendingcontact
        - editcontact
        - editcontactlocation
        - deletecontact
        - newcompany
        - newpendingcompany
        - editcompany
        - deletecompany
        - newfile
        - deletefile
        - newinvoice
        - editinvoice
        - deleteinvoice
        - newmessage
        - editmessage
        - deletemessage
        - newproject
        - editproject
        - editstageproject
        - deleteproject
        - completeproject
        - restoreProject
        - newprojectrequest
        - editprojectrequest
        - deleteprojectrequest
        - approveprojectrequest
        - declineprojectrequest
        - newquote
        - editquote
        - deletequote
        - newsharednote
        - editsharednote
        - deletesharednote
        - newtask
        - edittask
        - deletetask
        - completetask
        - reactivatetask
        - newtime
        - edittime
        - deletetime
        - starttimer
        - stoptimer
        - unknown
        example: newproject
        type: string
      url:
        example: https://example.com/webhook
        type: string
    type: object
  handlers.UpdateRolePayload:
    properties:
      color:
        example: A4C0DE
        type: string
      contactid:
        items:
          type: integer
        type: array
      displayorder:
        example: 1
        type: integer
      name:
        example: Project Manager
        type: string
      permissions:
        items:
          $ref: '#/definitions/handlers.SetRolePermissionInput'
        type: array
    type: object
  handlers.UpdateTeamPayload:
    properties:
      code:
        example: ENG
        type: string
      groupids:
        example: 1,2,3
        type: string
      name:
        example: Engineering
        type: string
      sortorder:
        example: "1"
        type: string
    type: object
  handlers.UpdateTimelogContactRequest:
    properties:
      contactid:
        example: 5
        type: integer
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.UpdateTimelogInvoiceItemRequest:
    properties:
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.UpdateTimelogRateRequest:
    properties:
      hourlyrateserviceid:
        example: 7
        type: integer
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.UpdateTimelogUnInvoiceRequest:
    properties:
      ids:
        example:
        - 1
        - 2
        - 3
        items:
          type: integer
        type: array
    type: object
  handlers.WorkStageListResponse:
    properties:
      data:
        items:
          $ref: '#/definitions/handlers.WorkStageResponse'
        type: array
      meta:
        $ref: '#/definitions/models.MetaResponse'
      status:
        example: success
        type: string
    type: object
  handlers.WorkStageResponse:
    properties:
      color:
        example: '#2E86C1'
        type: string
      deleted:
        example: false
        type: boolean
      divisionid:
        example: 1
        type: integer
      id:
        example: 1
        type: integer
      name:
        example: In Progress
        type: string
      nextstage:
        example: false
        type: boolean
      type:
        example: project
        type: string
      workstate:
        example: active
        type: string
      worktypeid:
        items:
          type: integer
        type: array
    type: object
  handlers.settingsAccountData:
    properties:
      accounttype:
        example: business
        type: string
      accounturl:
        example: mycompany.proworkflow.com
        type: string
      currency:
        example: USD
        type: string
      dateformat:
        example: dd/mm/yyyy
        type: string
      looknfeel:
        $ref: '#/definitions/handlers.settingsAccountLooknfeel'
      plan:
        $ref: '#/definitions/handlers.settingsAccountPlan'
      projectvariable:
        example: project
        type: string
      taskordering:
        example: manual
        type: string
      time:
        example: "24"
        type: string
      timetrackinginactivetasks:
        example: "false"
        type: string
    type: object
  handlers.settingsAccountLooknfeel:
    properties:
      colors:
        $ref: '#/definitions/handlers.settingsAccountLooknfeelColors'
      colorscheme:
        example: default
        type: string
      logo:
        example: https://cdn.proworkflow.com/images/logo.png
        type: string
    type: object
  handlers.settingsAccountLooknfeelColors:
    properties:
      headerprimary:
        example: '#1a73e8'
        type: string
      headersecondary:
        example: '#1558b0'
        type: string
      headertext:
        example: '#ffffff'
        type: string
      linktext:
        example: '#1a73e8'
        type: string
      tab:
        example: '#f1f3f4'
        type: string
      tabhover:
        example: '#e8eaed'
        type: string
    type: object
  handlers.settingsAccountPlan:
    properties:
      invoices:
        type: boolean
      plan:
        type: integer
      quotes:
        type: boolean
    type: object
  handlers.settingsAccountPlanData:
    properties:
      invoices:
        type: boolean
      plan:
        example: Advanced
        type: string
      quotes:
        type: boolean
    type: object
  handlers.settingsAccountPlanResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.settingsAccountPlanData'
      status:
        example: success
        type: string
    type: object
  handlers.settingsAccountResponse:
    properties:
      data:
        $ref: '#/definitions/handlers.settingsAccountData'
      status:
        example: success
        type: string
    type: object
  models.ErrorResponse:
    properties:
      data:
        items:
          type: string
        type: array
      status:
        example: Error
        type: string
    type: object
  models.MetaResponse:
    properties:
      count:
        type: integer
      total:
        type: integer
    type: object
  models.SuccessResponse:
    properties:
      data: {}
      message:
        example: Operation completed
        type: string
      status:
        example: success
        type: string
    type: object
host: api.proworkflow.com
info:
  contact:
    email: support@proworkflow.com
    name: API Support
    url: https://www.proworkflow.com/support
  description: ProWorkflow Management API - REST API for managing projects, companies,
    contacts, invoices, quotes, and related business data
  license:
    name: Proprietary
    url: https://www.proworkflow.com/license
  termsOfService: https://www.proworkflow.com/terms
  title: ProWorkflow API
  version: "4.0"
paths:
  /companies:
    get:
      consumes:
      - application/json
      description: Returns a list of Companies based on the filters specified. The
        fields parameter allows you to choose which data fields to return for each
        Company.
      parameters:
      - default: code,name,type
        description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>code</b> - Company code identifier</li><li><b>contacts</b> -
          Associated contacts as a JSON array [{id, firstname, lastname}] (use contactdetails
          field or query param to include email, phone, image)</li><li><b>contactdetails</b>
          - Alias for contacts field with email, phone, and image included</li><li><b>email</b>
          - Primary email address</li><li><b>fax</b> - Fax number</li><li><b>image</b>
          - Company logo/image URL</li><li><b>lastmodifiedutc</b> - Last modified
          date in ISO8601 format (UTC)</li><li><b>maincompanylocationid</b> - ID of
          the primary company location</li><li><b>name</b> - Company name</li><li><b>phone</b>
          - Primary phone number</li><li><b>tags</b> - Company tags as a JSON array
          [{id, name, color}]</li><li><b>type</b> - Company type (client, contractor,
          staff, other)</li><li><b>website</b> - Company website URL</li></ul>'
        in: query
        name: fields
        type: string
      - default: false
        description: Return contact details (email, image, phone)
        in: query
        name: contactdetails
        type: boolean
      - default: false
        description: Include the company's locations array in each result
        in: query
        name: includelocations
        type: boolean
      - description: 'Deprecated: use name, code, email, or q+qfields instead. Search
          by name or code. Use ! for negation.'
        in: query
        name: search
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation.'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use code or q+qfields instead. Search by code. Use
          ! for negation.'
        in: query
        name: searchcode
        type: string
      - description: 'Deprecated: use email or q+qfields instead. Search by email.
          Use ! for negation.'
        in: query
        name: searchemail
        type: string
      - description: Exact name match
        in: query
        name: name
        type: string
      - description: Exact code match
        in: query
        name: code
        type: string
      - description: Exact email match
        in: query
        name: email
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - code
        - email
        in: query
        name: qfields
        type: string
      - description: Company Type. <ul><li><b>client</b> - Client Companies</li><li><b>contractor</b>
          - Contractor Companies</li><li><b>other</b> - Other Companies</li><li><b>staff</b>
          - Staff Companies</li></ul>
        enum:
        - client
        - contractor
        - other
        - staff
        in: query
        name: type
        type: string
      - description: 'Tag ID or List of Tag IDs. <ul><li><b>tagid/s</b> - Companies
          with at least one of the specified Tag ID/s<br>Example: 1,2,3</li></ul>'
        in: query
        name: tagid
        type: string
      - description: 'Division ID (Advanced plan only). <ul><li><b>divisionid</b>
          - Companies in specified Division<br>Example: 1</li></ul>'
        in: query
        name: divisionid
        type: string
      - description: 'Companies added/edited on or after this date (UTC time). <ul><li><b>Specific
          date & time</b> - Date in ISO8601 (yyyy-mm-ddThh:mm) format<br>Example:
          2014-01-18T13:20</li><li><b>Xn/h/d/w/m</b> - X minutes/hours/days/weeks/months
          ago<br>Example: 12h</li></ul>'
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: 'Companies added/edited on or before this date (UTC time). <ul><li><b>Specific
          date & time</b> - Date in ISO8601 (yyyy-mm-ddThh:mm) format<br>Example:
          2014-01-18T13:20</li><li><b>Xn/h/d/w/m</b> - X minutes/hours/days/weeks/months
          ago<br>Example: 12h</li></ul>'
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Companies with ID less than or equal to this value
        in: query
        name: idfrom
        type: string
      - description: Companies with ID greater than or equal to this value
        in: query
        name: idto
        type: string
      - description: List of Company IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - code
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Companies
      tags:
      - companies
    post:
      consumes:
      - application/json
      description: Creates one or more companies. Can accept a single company object
        or an array of companies in the 'companies' field.
      parameters:
      - description: Company data
        in: body
        name: company
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateCompanyPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Company/Companies
      tags:
      - companies
  /companies/{companyid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a company (marks as deleted)
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: "false"
        description: Also delete company contacts
        enum:
        - "true"
        - "false"
        in: query
        name: deletecontacts
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Company
      tags:
      - companies
    get:
      consumes:
      - application/json
      description: Returns details for a single company
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyGetResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Company
      tags:
      - companies
    put:
      consumes:
      - application/json
      description: Updates an existing company
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Company data
        in: body
        name: company
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateCompanyPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Company
      tags:
      - companies
  /companies/{companyid}/contacts:
    get:
      consumes:
      - application/json
      description: Returns a list of Contacts belonging to the specified Company.
        Supports the same filters as GET /contacts.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: firstname,lastname,type
        description: 'Comma-separated fields to return. Available fields: firstname,
          lastname, company, title, phone, fax, email, address, type, image, lastmodified,
          tags, groups, teams, roles'
        in: query
        name: fields
        type: string
      - description: Search by name. Use ! for negation
        in: query
        name: searchname
        type: string
      - description: Search by email. Use ! for negation
        in: query
        name: searchemail
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Role IDs (comma-separated)
        in: query
        name: roleid
        type: string
      - description: Group IDs (comma-separated)
        in: query
        name: groupid
        type: string
      - description: Pending status
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Login access filter
        enum:
        - "true"
        - "false"
        in: query
        name: allowlogin
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: 'Records modified on or after this date (ISO8601 or relative:
          12h, 5d)'
        in: query
        name: lastmodifiedfrom
        type: string
      - description: Records modified on or before this date (ISO8601 or relative)
        in: query
        name: lastmodifiedto
        type: string
      - description: Records modified on or after this date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Records modified on or before this date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Records with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Records with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Contact IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: lastname
        description: Sort field
        enum:
        - id
        - firstname
        - lastname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contacts for a Company
      tags:
      - contacts
    post:
      consumes:
      - application/json
      description: Creates one or more Contacts and associates them with the specified
        Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CompanyContactCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Contacts for a Company
      tags:
      - contacts
  /companies/{companyid}/invoices:
    get:
      consumes:
      - application/json
      description: Returns a list of Invoices for the specified Company. Supports
        the same filters as GET /invoices, scoped to the given company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: number,title,company,status,totals,projectid,invoiceddate,duedate
        description: Comma-separated fields to return
        in: query
        name: fields
        type: string
      - description: Search by number or title. Use ! for negation
        in: query
        name: search
        type: string
      - description: Search by invoice number. Use ! for negation
        in: query
        name: searchnumber
        type: string
      - description: Search by invoice title. Use ! for negation
        in: query
        name: searchtitle
        type: string
      - description: Invoice status
        enum:
        - draft
        - submitted
        - authorised
        - paid
        - voided
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Filter by taxable status
        enum:
        - "true"
        - "false"
        - all
        in: query
        name: taxable
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project category IDs (comma-separated)
        in: query
        name: projectcategoryid
        type: string
      - description: Project manager Contact IDs (comma-separated)
        in: query
        name: managerid
        type: string
      - description: 'Invoiced date from (ISO8601 or relative: 12h, 5d)'
        in: query
        name: invoiceddatefrom
        type: string
      - description: Invoiced date to (ISO8601 or relative)
        in: query
        name: invoiceddateto
        type: string
      - description: Due date from (ISO8601 or relative)
        in: query
        name: duedatefrom
        type: string
      - description: Due date to (ISO8601 or relative)
        in: query
        name: duedateto
        type: string
      - description: Paid date from (ISO8601 or relative)
        in: query
        name: paiddatefrom
        type: string
      - description: Paid date to (ISO8601 or relative)
        in: query
        name: paiddateto
        type: string
      - description: Grand total minimum
        in: query
        name: grandtotalfrom
        type: string
      - description: Grand total maximum
        in: query
        name: grandtotalto
        type: string
      - description: Last modified from in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified to in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Filter invoices with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Filter invoices with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Invoice IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - invoiceddate
        - duedate
        - companyname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoices for a Company
      tags:
      - companies
  /companies/{companyid}/items:
    get:
      consumes:
      - application/json
      description: Returns a list of Items for a Company based on the specified filters.
        The fields parameter allows you to choose which data fields to return for
        each Item.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: title,status,priority
        description: 'Comma-separated fields to return. Available: title, code, number,
          description, status, priority, percentcomplete, position, project, company,
          dates, time, billable, workstageid, parentid, phasename, assignedto, tags,
          lastmodified, all'
        in: query
        name: fields
        type: string
      - description: Search by name or code. Use ! prefix for negation
        example: design
        in: query
        name: search
        type: string
      - default: active
        description: Filter by status
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Filter by priority (1=Very High to 5=Very Low)
        in: query
        name: priority
        type: string
      - description: Contact IDs assigned to item, or 'me'
        example: 1,2
        in: query
        name: contacts
        type: string
      - default: any
        description: Mode for contacts filter
        enum:
        - any
        - all
        in: query
        name: contactsmode
        type: string
      - description: Tag ID or list of Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - description: Items modified on or after this date (UTC). ISO8601 or relative
          (12h, 5d, 2w, 1m)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Items modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Items with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Items with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Item IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: title
        description: Sort field
        enum:
        - id
        - title
        - code
        - priority
        - startdate
        - duedate
        - completedate
        - status
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Items for a Company
      tags:
      - companies
  /companies/{companyid}/locations:
    get:
      consumes:
      - application/json
      description: Returns the locations belonging to the specified Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: name,companyid
        description: Comma-separated fields to return (or 'all')
        in: query
        name: fields
        type: string
      - description: Search by name. Prefix with ! for negation
        in: query
        name: search
        type: string
      - description: Filter by active status
        enum:
        - "true"
        - "false"
        in: query
        name: active
        type: string
      - description: Locations modified on or after this date (UTC). ISO8601 or relative
          (12h, 5d)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Locations modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - code
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyLocationListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Locations for a Company
      tags:
      - companies
    post:
      consumes:
      - application/json
      description: Creates a new location and associates it with the specified Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Company location data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CompanyLocationCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Location for a Company
      tags:
      - companies
  /companies/{companyid}/locations/{locationid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes a location belonging to the specified Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Company Location ID
        in: path
        name: locationid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: (Company Locations) Delete a Company Location
      tags:
      - companies
    get:
      consumes:
      - application/json
      description: Returns a single location belonging to the specified Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Company Location ID
        in: path
        name: locationid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyLocationGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: (Company Locations) Get a Company Location
      tags:
      - companies
    put:
      consumes:
      - application/json
      description: Updates an existing location belonging to the specified Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Company Location ID
        in: path
        name: locationid
        required: true
        type: integer
      - description: Company location update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CompanyLocationUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: (Company Locations) Update a Company Location
      tags:
      - companies
  /companies/{companyid}/notes:
    get:
      consumes:
      - application/json
      description: Returns a list of Notes for a Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: note,creator,datecreated
        description: 'Comma-separated fields to return. Available fields: <ul><li><b>note</b>
          - Note content</li><li><b>company</b> - Company ID</li><li><b>creator</b>
          - Creator ID and name (shorthand for creatorid + creatorname)</li><li><b>creatorid</b>
          - Creator contact ID</li><li><b>creatorname</b> - Creator full name</li><li><b>datecreated</b>
          - Date created</li><li><b>lastmodifiedutc</b> - Last modified date (UTC)</li></ul>'
        in: query
        name: fields
        type: string
      - description: Search note content. Use ! for negation
        in: query
        name: search
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: integer
      - description: Notes modified on or after this date (UTC). ISO8601 or relative
          (12h, 5d, 2w, 1m)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Notes modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      - default: datecreated
        description: Sort field
        enum:
        - id
        - datecreated
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyNoteListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Company Notes
      tags:
      - companies
    post:
      consumes:
      - application/json
      description: Creates one or more Notes for a specified Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CompanyNoteCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Company Notes
      tags:
      - companies
  /companies/{companyid}/notes/{noteid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Company Note.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Company Note
      tags:
      - companies
    get:
      consumes:
      - application/json
      description: Returns a single Note for a Company by ID.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyNoteGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Company Note
      tags:
      - companies
    put:
      consumes:
      - application/json
      description: Updates a Company Note.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CompanyNoteUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Company Note
      tags:
      - companies
  /companies/{companyid}/projects:
    get:
      consumes:
      - application/json
      description: Returns a list of Projects for the specified Company. Supports
        the same filters as GET /projects, scoped to the given company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: title,number,company,startdate,duedate
        description: Comma-separated fields to return
        in: query
        name: fields
        type: string
      - description: Search by number or title. Use ! for negation
        in: query
        name: search
        type: string
      - description: Search by project number. Use ! for negation
        in: query
        name: searchnumber
        type: string
      - description: Project status
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Manager Contact IDs (comma-separated). Use ! for negation, or
          'me'/'all'
        in: query
        name: managerid
        type: string
      - description: Contact IDs (comma-separated). Use ! for negation, or 'me'/'all'
        in: query
        name: contacts
        type: string
      - default: any
        description: Contacts filter mode
        enum:
        - any
        - all
        in: query
        name: contactsmode
        type: string
      - description: Team IDs (comma-separated, Advanced plan only)
        in: query
        name: teamid
        type: string
      - description: Group IDs (comma-separated, Advanced plan only)
        in: query
        name: groupid
        type: string
      - description: Category IDs (comma-separated)
        in: query
        name: categoryid
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Priority values 1-5 (comma-separated)
        in: query
        name: priority
        type: string
      - description: Workstage IDs (comma-separated)
        in: query
        name: workstageid
        type: string
      - description: 'Start date from (yyyy-mm-dd or relative: +/-Xd/w/m/y)'
        in: query
        name: startdatefrom
        type: string
      - description: Start date to (yyyy-mm-dd or relative)
        in: query
        name: startdateto
        type: string
      - description: Due date from (yyyy-mm-dd or relative)
        in: query
        name: duedatefrom
        type: string
      - description: Due date to (yyyy-mm-dd or relative)
        in: query
        name: duedateto
        type: string
      - description: Complete date from (yyyy-mm-dd or relative)
        in: query
        name: completedatefrom
        type: string
      - description: Complete date to (yyyy-mm-dd or relative)
        in: query
        name: completedateto
        type: string
      - description: Last modified from in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified to in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Filter projects with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Filter projects with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Project IDs (comma-separated)
        in: query
        name: id
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - startdate
        - duedate
        - completedate
        - companyname
        - categoryname
        - priority
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Projects for a Company
      tags:
      - companies
    post:
      consumes:
      - application/json
      description: Creates one or more Projects for a specified Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CompanyProjectCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Company Projects
      tags:
      - companies
  /companies/{companyid}/quotes:
    get:
      consumes:
      - application/json
      description: Returns a list of Quotes for the specified Company. Supports the
        same filters as GET /quotes, scoped to the given company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: number,title,company,status,totals,quoteddate
        description: Comma-separated fields to return
        in: query
        name: fields
        type: string
      - description: Search by number or title. Use ! for negation
        in: query
        name: search
        type: string
      - description: Search by quote number. Supports ! for negation
        in: query
        name: searchnumber
        type: string
      - description: Search by quote title. Supports ! for negation
        in: query
        name: searchtitle
        type: string
      - description: Quote status
        enum:
        - pending
        - sent
        - accepted
        - addedtoproject
        - declined
        - expired
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Quote type
        enum:
        - estimate
        - quote
        - all
        in: query
        name: type
        type: string
      - description: Filter by taxable status
        enum:
        - "true"
        - "false"
        - all
        in: query
        name: taxable
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Project manager Contact IDs (comma-separated)
        in: query
        name: managerid
        type: string
      - description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project category IDs (comma-separated)
        in: query
        name: projectcategoryid
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: 'Quoted date from (ISO8601 or relative: 12h, 5d)'
        in: query
        name: quoteddatefrom
        type: string
      - description: Quoted date to (ISO8601 or relative)
        in: query
        name: quoteddateto
        type: string
      - description: Approved date from (ISO8601 or relative)
        in: query
        name: approveddatefrom
        type: string
      - description: Approved date to (ISO8601 or relative)
        in: query
        name: approveddateto
        type: string
      - description: Valid to date from (ISO8601 or relative)
        in: query
        name: validtodatefrom
        type: string
      - description: Valid to date to (ISO8601 or relative)
        in: query
        name: validtodateto
        type: string
      - description: Grand total minimum
        in: query
        name: grandtotalfrom
        type: string
      - description: Grand total maximum
        in: query
        name: grandtotalto
        type: string
      - description: Group results by
        enum:
        - company
        - project
        - status
        - day
        - week
        - month
        - year
        in: query
        name: subtotals
        type: string
      - description: Date field for subtotals grouping
        enum:
        - quoted
        - approved
        in: query
        name: subtotalsdateoption
        type: string
      - description: Last modified from in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified to in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Filter quotes with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Filter quotes with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Quote IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - quoteddate
        - validtodate
        - companyname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quotes for a Company
      tags:
      - companies
  /companies/{companyid}/summary:
    get:
      consumes:
      - application/json
      description: Returns a summary of Contacts, Invoices, Projects, Quotes and Phases
        for the specified Company in a single request.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: all
        description: Comma-separated data types to include, or 'all'
        example: contacts,projects
        in: query
        name: types
        type: string
      - default: "false"
        description: Return total result count per section (useful with pagination)
        enum:
        - "true"
        - "false"
        in: query
        name: includetotals
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size per section (must be used with pagenumber)
        example: 10
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanySummaryResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Company Summary
      tags:
      - companies
  /companies/{companyid}/tags:
    get:
      consumes:
      - application/json
      description: Returns a list of tags linked to the specified Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: name,color
        description: 'Comma-separated fields to return. Available fields: <ul><li><b>name</b>
          - Tag name</li><li><b>color</b> - Tag color (hex)</li><li><b>sortorder</b>
          - Display sort order</li><li><b>lastmodifiedutc</b> - Last modified date
          (UTC)</li></ul>'
        in: query
        name: fields
        type: string
      - description: Search by tag name. Use ! for negation
        in: query
        name: search
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Tags modified on or after this date (UTC). ISO8601 or relative
          (12h, 5d, 2w, 1m)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Tags modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      - default: sortorder
        description: Sort field
        enum:
        - name
        - sortorder
        - lastmodifiedutc
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyTagListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Tags for a Company
      tags:
      - companies
    put:
      consumes:
      - application/json
      description: Updates the tags linked to a Company.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CompanyTagUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Company Tags
      tags:
      - companies
  /companies/{companyid}/time:
    get:
      consumes:
      - application/json
      description: Returns a list of Time Records for the specified Company. No default
        date range is applied — all time for the company is returned unless trackedfrom/trackedto
        are specified.
      parameters:
      - description: Company ID
        in: path
        name: companyid
        required: true
        type: integer
      - default: contact,item,dates,timetracked
        description: 'Comma-separated fields to return. Available: contact, item,
          project, company, dates, timetracked, notes, billable, lastmodified'
        in: query
        name: fields
        type: string
      - description: 'Contact filter: contact IDs (comma-separated), ''me'', or ''all'''
        in: query
        name: contacts
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: Item IDs (comma-separated)
        in: query
        name: itemid
        type: string
      - description: Project Category IDs (comma-separated)
        in: query
        name: categoryid
        type: string
      - description: 'Time tracked on or after this date. Accepts yyyy-mm-dd or relative:
          -6d, -1w'
        example: -6d
        in: query
        name: trackedfrom
        type: string
      - description: 'Time tracked on or before this date. Accepts yyyy-mm-dd or relative:
          +0d'
        example: +0d
        in: query
        name: trackedto
        type: string
      - default: all
        description: Billable filter
        enum:
        - billable
        - nonbillable
        - all
        in: query
        name: billable
        type: string
      - default: all
        description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - default: all
        description: Filter by item activeworkstate
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Search by notes. Use ! for negation
        in: query
        name: searchnotes
        type: string
      - description: Search by item name. Use ! for negation
        in: query
        name: searchitem
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Records modified on or after this date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Records modified on or before this date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Records with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Records with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Time Record IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - date
        - projectid
        - itemid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TimeListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Time Records for a Company
      tags:
      - companies
  /companies/client:
    get:
      consumes:
      - application/json
      description: Returns a list of Client Companies based on the specified filters.
        Equivalent to GET /companies with type=client.
      parameters:
      - default: code,name,type
        description: Comma-separated list of fields to return
        in: query
        name: fields
        type: string
      - default: false
        description: Return contact details (email, image, phone)
        in: query
        name: contactdetails
        type: boolean
      - description: Search string. Use ! for negation
        in: query
        name: search
        type: string
      - description: Search by name. Use ! for negation
        in: query
        name: searchname
        type: string
      - description: Search by code. Use ! for negation
        in: query
        name: searchcode
        type: string
      - description: Search by email. Use ! for negation
        in: query
        name: searchemail
        type: string
      - description: Tag ID or comma-separated list of Tag IDs
        in: query
        name: tagid
        type: string
      - default: "false"
        description: Pending status
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Last modified from date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified to date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Filter companies with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Filter companies with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Company IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - code
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Client Companies
      tags:
      - companies
  /companies/contractor:
    get:
      consumes:
      - application/json
      description: Returns a list of Contractor Companies based on the specified filters.
        Equivalent to GET /companies with type=contractor.
      parameters:
      - default: code,name,type
        description: Comma-separated list of fields to return
        in: query
        name: fields
        type: string
      - default: false
        description: Return contact details (email, image, phone)
        in: query
        name: contactdetails
        type: boolean
      - description: 'Deprecated: use name, code, email, or q+qfields instead. Search
          by name or code. Use ! for negation'
        in: query
        name: search
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use code or q+qfields instead. Search by code. Use
          ! for negation'
        in: query
        name: searchcode
        type: string
      - description: 'Deprecated: use email or q+qfields instead. Search by email.
          Use ! for negation'
        in: query
        name: searchemail
        type: string
      - description: Exact name match
        in: query
        name: name
        type: string
      - description: Exact code match
        in: query
        name: code
        type: string
      - description: Exact email match
        in: query
        name: email
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - code
        - email
        in: query
        name: qfields
        type: string
      - description: Tag ID or comma-separated list of Tag IDs
        in: query
        name: tagid
        type: string
      - default: "false"
        description: Pending status
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Last modified from date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified to date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Filter companies with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Filter companies with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Company IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - code
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contractor Companies
      tags:
      - companies
  /companies/staff:
    get:
      consumes:
      - application/json
      description: Returns a list of Staff Companies based on the specified filters.
        Equivalent to GET /companies with type=staff.
      parameters:
      - default: code,name,type
        description: Comma-separated list of fields to return
        in: query
        name: fields
        type: string
      - default: false
        description: Return contact details (email, image, phone)
        in: query
        name: contactdetails
        type: boolean
      - description: 'Deprecated: use name, code, email, or q+qfields instead. Search
          by name or code. Use ! for negation'
        in: query
        name: search
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use code or q+qfields instead. Search by code. Use
          ! for negation'
        in: query
        name: searchcode
        type: string
      - description: 'Deprecated: use email or q+qfields instead. Search by email.
          Use ! for negation'
        in: query
        name: searchemail
        type: string
      - description: Exact name match
        in: query
        name: name
        type: string
      - description: Exact code match
        in: query
        name: code
        type: string
      - description: Exact email match
        in: query
        name: email
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - code
        - email
        in: query
        name: qfields
        type: string
      - description: Tag ID or comma-separated list of Tag IDs
        in: query
        name: tagid
        type: string
      - default: "false"
        description: Pending status
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Last modified from date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified to date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Filter companies with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Filter companies with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Company IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - code
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CompanyListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Staff Companies
      tags:
      - companies
  /companies/tags:
    delete:
      consumes:
      - application/json
      description: Removes one or more Tags from one or more Companies.
      parameters:
      - description: Company IDs and Tag IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RemoveTagsFromCompaniesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Tags from Companies
      tags:
      - companies
    post:
      consumes:
      - application/json
      description: Adds one or more Tags to one or more Companies.
      parameters:
      - description: Company IDs and Tag IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.TagsToCompaniesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Tags to Companies
      tags:
      - companies
  /contacts:
    get:
      consumes:
      - application/json
      description: View Contacts. Returns a list of Contacts based on the filters
        specified.
      parameters:
      - default: id,name,company,type
        description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>address</b> - Postal address (computed: combines address1, address2,
          address3 into a single string)</li><li><b>company</b> - Associated company
          ID and name</li><li><b>image</b> - Contact profile image URL</li><li><b>lastmodified</b>
          - Last modified date in ISO8601 format (UTC)</li><li><b>name</b> - Contact
          full name (firstname + lastname)</li><li><b>notes</b> - Contact notes as
          a JSON array [{id, content, date, authorid, authorname}]</li><li><b>payrate</b>
          - Pay rate, pay rate multiplier, and default hourly rate ID</li><li><b>roles</b>
          - Contact roles as a JSON array [{id, name, color}]</li><li><b>status</b>
          - Contact status (active, inactive)</li><li><b>timezone</b> - IANA timezone
          identifier</li><li><b>type</b> - Contact type (client, contractor, staff,
          other)</li></ul>'
        in: query
        name: fields
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation.'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use email or q+qfields instead. Search by email.
          Use ! for negation.'
        in: query
        name: searchemail
        type: string
      - description: Exact name match (firstname + lastname)
        in: query
        name: name
        type: string
      - description: Exact email match
        in: query
        name: email
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - email
        in: query
        name: qfields
        type: string
      - description: Contact Type. <ul><li><b>client</b> - Client Contacts</li><li><b>contractor</b>
          - Contractor Contacts</li><li><b>other</b> - Other Contacts</li><li><b>staff</b>
          - Staff Contacts</li></ul>
        enum:
        - client
        - contractor
        - staff
        - other
        in: query
        name: type
        type: string
      - description: 'Tag ID or List of Tag IDs. <ul><li><b>tagid/s</b> - Contacts
          with at least one of the specified Tag ID/s<br>Example: 1,2,3</li></ul>'
        in: query
        name: tagid
        type: string
      - description: 'Role ID or List of Role IDs. <ul><li><b>roleid/s</b> - Contacts
          with at least one of the specified Role ID/s<br>Example: 1,2,3</li></ul>'
        in: query
        name: roleid
        type: string
      - description: Group ID or List of Group IDs (comma-separated). Contacts with
          at least one of the specified Group IDs
        example: 1,2,3
        in: query
        name: groupid
        type: string
      - default: "false"
        description: Pending status. <ul><li><b>true</b> - Pending Contacts</li><li><b>false</b>
          - Active Contacts</li></ul>
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Login status. <ul><li><b>true</b> - Contacts with Login Access</li><li><b>false</b>
          - Contacts without Login Access</li></ul>
        enum:
        - "true"
        - "false"
        in: query
        name: allowlogin
        type: string
      - description: 'Division ID (Advanced plan only). <ul><li><b>divisionid</b>
          - Contacts in specified Division<br>Example: 1</li></ul>'
        in: query
        name: divisionid
        type: string
      - description: 'Company ID. <ul><li><b>companyid</b> - Contacts in specified
          Company<br>Example: 1</li></ul>'
        in: query
        name: companyid
        type: string
      - description: 'Contacts added/edited on or after this date (UTC time). <ul><li><b>Specific
          date & time</b> - Date in ISO8601 (yyyy-mm-ddThh:mm) format<br>Example:
          2014-01-18T13:20</li><li><b>Xn/h/d/w/m</b> - X minutes/hours/days/weeks/months
          ago<br>Example: 12h</li></ul>'
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: 'Contacts added/edited on or before this date (UTC time). <ul><li><b>Specific
          date & time</b> - Date in ISO8601 (yyyy-mm-ddThh:mm) format<br>Example:
          2014-01-18T13:20</li><li><b>Xn/h/d/w/m</b> - X minutes/hours/days/weeks/months
          ago<br>Example: 12h</li></ul>'
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Contacts with ID greater than or equal to this value
        in: query
        name: idfrom
        type: string
      - description: Contacts with ID less than or equal to this value
        in: query
        name: idto
        type: string
      - description: List of Contact IDs (comma-separated)
        example: 1,2,3,4
        in: query
        name: id
        type: string
      - default: firstname
        description: Sort field
        enum:
        - id
        - firstname
        - lastname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contacts
      tags:
      - contacts
    post:
      consumes:
      - application/json
      description: Create one or more new contacts
      parameters:
      - description: Contact data
        in: body
        name: contact
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateContactPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Contacts
      tags:
      - contacts
  /contacts/{contactid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Contact
      tags:
      - contacts
    get:
      consumes:
      - application/json
      description: Returns details of a single Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactDetailResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contact
      tags:
      - contacts
    put:
      consumes:
      - application/json
      description: Updates an existing Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Contact data to update
        in: body
        name: contact
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateContactPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Contact
      tags:
      - contacts
  /contacts/{contactid}/groups:
    get:
      consumes:
      - application/json
      description: Returns a list of Teams &amp; Groups for a Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactGroupsResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contact Teams & Groups
      tags:
      - contacts
    put:
      consumes:
      - application/json
      description: Updates the groups assigned to a Staff Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Group IDs
        in: body
        name: groups
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateContactGroupsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Contact Groups
      tags:
      - contacts
  /contacts/{contactid}/items:
    get:
      consumes:
      - application/json
      description: Returns a list of Items (Tasks) assigned to the specified Contact.
        Supports the same filters as GET /items, scoped to the given contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - default: title,status,priority
        description: 'Comma-separated fields to return. Available: title, code, number,
          description, status, priority, percentcomplete, position, project, company,
          dates, time, billable, workstageid, parentid, phasename, assignedto, tags,
          lastmodified'
        in: query
        name: fields
        type: string
      - description: Search by name or code. Use ! for negation
        in: query
        name: search
        type: string
      - description: Search by name. Use ! for negation
        in: query
        name: searchname
        type: string
      - description: Search by description. Use ! for negation
        in: query
        name: searchdescription
        type: string
      - description: Search by code. Use ! for negation
        in: query
        name: searchcode
        type: string
      - default: active
        description: Item status
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Priority values 1-5 (comma-separated)
        in: query
        name: priority
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: Company IDs (comma-separated)
        in: query
        name: companyid
        type: string
      - description: Additional contact filter (comma-separated IDs, or 'me')
        in: query
        name: contacts
        type: string
      - default: any
        description: Mode for contacts filter
        enum:
        - any
        - all
        in: query
        name: contactsmode
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Work Stage ID
        in: query
        name: workstageid
        type: string
      - description: Start date from (yyyy-mm-dd)
        in: query
        name: startdatefrom
        type: string
      - description: Start date to (yyyy-mm-dd)
        in: query
        name: startdateto
        type: string
      - description: Due date from (yyyy-mm-dd)
        in: query
        name: duedatefrom
        type: string
      - description: Due date to (yyyy-mm-dd)
        in: query
        name: duedateto
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Items modified on or after this date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Items modified on or before this date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Items with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Items with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Item IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: title
        description: Sort field
        enum:
        - id
        - title
        - code
        - priority
        - startdate
        - duedate
        - completedate
        - status
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Items for a Contact
      tags:
      - contacts
    post:
      consumes:
      - application/json
      description: Assigns a Contact to one or more Items (Tasks).
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Item IDs to assign the contact to
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.AddContactItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Assign Contact to Items
      tags:
      - contacts
  /contacts/{contactid}/notes:
    get:
      consumes:
      - application/json
      description: Returns a list of Notes for a Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Division ID (Advanced plan only)
        example: 1
        in: query
        name: divisionid
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactNoteListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contact Notes
      tags:
      - contacts
    post:
      consumes:
      - application/json
      description: Creates one or more Notes for a Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Note data
        in: body
        name: note
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateContactNotePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Contact Notes
      tags:
      - contacts
  /contacts/{contactid}/notes/{noteid}:
    delete:
      responses: {}
    get:
      consumes:
      - application/json
      description: Returns a single Note for a Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactNoteGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contact Note
      tags:
      - contacts
    put:
      consumes:
      - application/json
      - application/json
      description: |-
        Soft deletes a Contact Note.
        Updates a Contact Note.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.UpdateContactNotePayload'
      produces:
      - application/json
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Contact Note
      tags:
      - contacts
      - contacts
  /contacts/{contactid}/permissions:
    get:
      consumes:
      - application/json
      description: Returns all permissions for a Staff contact. Use GET /settings/contacts/permissions
        to retrieve the list of available permission IDs.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            items:
              $ref: '#/definitions/handlers.ContactPermissionResponse'
            type: array
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get All Permissions for a Contact
      tags:
      - contacts
  /contacts/{contactid}/permissions/{permissionid}:
    get:
      consumes:
      - application/json
      description: Returns a single permission entry for a Staff contact. Use GET
        /settings/contacts/permissions to retrieve the list of available permission
        IDs.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Permission ID
        in: path
        name: permissionid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactPermissionResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Check a Single Permission for a Contact
      tags:
      - contacts
  /contacts/{contactid}/projects:
    delete:
      consumes:
      - application/json
      description: Removes a Contact from one or more Projects.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Project IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.ContactProjectsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Contact from Projects
      tags:
      - contacts
    get:
      consumes:
      - application/json
      description: Returns a list of Projects the specified Contact is assigned to
        (as staff, contractor, or client). Supports the same filters as GET /projects,
        scoped to the given contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - default: title,number,company,startdate,duedate
        description: Comma-separated fields to return
        in: query
        name: fields
        type: string
      - description: Search by number or title. Use ! for negation
        in: query
        name: search
        type: string
      - description: Search by project number. Use ! for negation
        in: query
        name: searchnumber
        type: string
      - description: Project status
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Manager Contact IDs (comma-separated). Use ! for negation, or
          'me'/'all'
        in: query
        name: managerid
        type: string
      - description: Additional contact filter (comma-separated IDs). Use ! for negation,
          or 'me'/'all'
        in: query
        name: contacts
        type: string
      - default: any
        description: Contacts filter mode
        enum:
        - any
        - all
        in: query
        name: contactsmode
        type: string
      - description: Team IDs (comma-separated, Advanced plan only)
        in: query
        name: teamid
        type: string
      - description: Group IDs (comma-separated, Advanced plan only)
        in: query
        name: groupid
        type: string
      - description: Category IDs (comma-separated)
        in: query
        name: categoryid
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Priority values 1-5 (comma-separated)
        in: query
        name: priority
        type: string
      - description: Workstage IDs (comma-separated)
        in: query
        name: workstageid
        type: string
      - description: 'Start date from (yyyy-mm-dd or relative: +/-Xd/w/m/y)'
        in: query
        name: startdatefrom
        type: string
      - description: Start date to (yyyy-mm-dd or relative)
        in: query
        name: startdateto
        type: string
      - description: Due date from (yyyy-mm-dd or relative)
        in: query
        name: duedatefrom
        type: string
      - description: Due date to (yyyy-mm-dd or relative)
        in: query
        name: duedateto
        type: string
      - description: Complete date from (yyyy-mm-dd or relative)
        in: query
        name: completedatefrom
        type: string
      - description: Complete date to (yyyy-mm-dd or relative)
        in: query
        name: completedateto
        type: string
      - description: Last modified from in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified to in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Filter projects with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Filter projects with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Project IDs (comma-separated)
        in: query
        name: id
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - startdate
        - duedate
        - completedate
        - companyname
        - categoryname
        - priority
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Projects for a Contact
      tags:
      - contacts
    put:
      consumes:
      - application/json
      description: Adds a Contact to one or more Projects.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Project IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.ContactProjectsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Contact to Projects
      tags:
      - contacts
  /contacts/{contactid}/roles:
    delete:
      consumes:
      - application/json
      description: Removes one or more Roles from a Staff Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Role IDs to remove
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.ContactRolesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Roles from a Contact
      tags:
      - contacts
    get:
      consumes:
      - application/json
      description: Returns a list of roles for a Staff Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactRoleListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Roles for a Staff Contact
      tags:
      - contacts
    post:
      consumes:
      - application/json
      description: Assigns one or more Roles to a Staff Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Role IDs to assign
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.ContactRolesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Roles to a Contact
      tags:
      - contacts
  /contacts/{contactid}/tags:
    get:
      consumes:
      - application/json
      description: Returns a list of tags linked to the specified Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - description: Tags modified on or after this date (UTC). ISO8601 or relative
          (12h, 5d, 2w, 1m)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Tags modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactTagListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Tags for a Contact
      tags:
      - contacts
    put:
      consumes:
      - application/json
      description: Updates the tags linked to a Contact.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - description: Tag IDs
        in: body
        name: tags
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateContactTagsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Contact Tags
      tags:
      - contacts
  /contacts/{contactid}/time:
    get:
      consumes:
      - application/json
      description: Returns a list of Time Records tracked by the specified Contact.
        No default date range is applied — all time for the contact is returned unless
        trackedfrom/trackedto are specified.
      parameters:
      - description: Contact ID
        in: path
        name: contactid
        required: true
        type: integer
      - default: contact,item,dates,timetracked
        description: 'Comma-separated fields to return. Available: contact, item,
          project, company, dates, timetracked, notes, billable, lastmodified'
        in: query
        name: fields
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: Item IDs (comma-separated)
        in: query
        name: itemid
        type: string
      - description: Company IDs (comma-separated)
        in: query
        name: companyid
        type: string
      - description: Project Category IDs (comma-separated)
        in: query
        name: categoryid
        type: string
      - description: 'Time tracked on or after this date. Accepts yyyy-mm-dd or relative:
          -6d, -1w'
        example: -6d
        in: query
        name: trackedfrom
        type: string
      - description: 'Time tracked on or before this date. Accepts yyyy-mm-dd or relative:
          +0d'
        example: +0d
        in: query
        name: trackedto
        type: string
      - default: all
        description: Billable filter
        enum:
        - billable
        - nonbillable
        - all
        in: query
        name: billable
        type: string
      - default: all
        description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - default: all
        description: Filter by item activeworkstate
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Search by notes. Use ! for negation
        in: query
        name: searchnotes
        type: string
      - description: Search by item name. Use ! for negation
        in: query
        name: searchitem
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Records modified on or after this date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Records modified on or before this date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Records with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Records with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Time Record IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - date
        - projectid
        - itemid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TimeListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Time Records for a Contact
      tags:
      - contacts
  /contacts/client:
    get:
      consumes:
      - application/json
      description: Returns a list of Client Contacts. Supports the same filters as
        GET /contacts, scoped to type=client.
      parameters:
      - default: id,name,company,type
        description: 'Comma-separated fields to return. Available: id, name, company,
          type, email, phone, fax, address, title, image, lastmodified, logindetails,
          roles, tags, teams, groups, notes'
        in: query
        name: fields
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use email or q+qfields instead. Search by email.
          Use ! for negation'
        in: query
        name: searchemail
        type: string
      - description: Exact name match (firstname + lastname)
        in: query
        name: name
        type: string
      - description: Exact email match
        in: query
        name: email
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - email
        in: query
        name: qfields
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Role IDs (comma-separated)
        in: query
        name: roleid
        type: string
      - description: Group IDs (comma-separated)
        in: query
        name: groupid
        type: string
      - description: Pending status
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Login access filter
        enum:
        - "true"
        - "false"
        in: query
        name: allowlogin
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: integer
      - description: Company ID
        in: query
        name: companyid
        type: integer
      - description: Records modified on or after this date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Records modified on or before this date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Records with ID >= this value
        in: query
        name: idfrom
        type: integer
      - description: Records with ID <= this value
        in: query
        name: idto
        type: integer
      - description: List of Contact IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: firstname
        description: Sort field
        enum:
        - id
        - firstname
        - lastname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Client Contacts
      tags:
      - contacts
  /contacts/contractor:
    get:
      consumes:
      - application/json
      description: Returns a list of Contractor Contacts. Supports the same filters
        as GET /contacts, scoped to type=contractor.
      parameters:
      - default: id,name,company,type
        description: 'Comma-separated fields to return. Available: id, name, company,
          type, email, phone, fax, address, title, image, lastmodified, logindetails,
          roles, tags, teams, groups, notes'
        in: query
        name: fields
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use email or q+qfields instead. Search by email.
          Use ! for negation'
        in: query
        name: searchemail
        type: string
      - description: Exact name match (firstname + lastname)
        in: query
        name: name
        type: string
      - description: Exact email match
        in: query
        name: email
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - email
        in: query
        name: qfields
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Role IDs (comma-separated)
        in: query
        name: roleid
        type: string
      - description: Group IDs (comma-separated)
        in: query
        name: groupid
        type: string
      - description: Pending status
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Login access filter
        enum:
        - "true"
        - "false"
        in: query
        name: allowlogin
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: integer
      - description: Company ID
        in: query
        name: companyid
        type: integer
      - description: Records modified on or after this date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Records modified on or before this date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Records with ID >= this value
        in: query
        name: idfrom
        type: integer
      - description: Records with ID <= this value
        in: query
        name: idto
        type: integer
      - description: List of Contact IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: firstname
        description: Sort field
        enum:
        - id
        - firstname
        - lastname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contractor Contacts
      tags:
      - contacts
  /contacts/groups:
    delete:
      consumes:
      - application/json
      description: Removes one or more Groups from one or more Contacts.
      parameters:
      - description: Contact IDs and Group IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.GroupsToContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Groups from Contacts
      tags:
      - contacts
    post:
      consumes:
      - application/json
      description: Adds one or more Groups to one or more Contacts.
      parameters:
      - description: Contact IDs and Group IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.GroupsToContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Groups to Contacts
      tags:
      - contacts
  /contacts/roles:
    delete:
      consumes:
      - application/json
      description: Removes one or more Roles from one or more Staff Contacts.
      parameters:
      - description: Contact IDs and Role IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RolesToContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Roles from Contacts
      tags:
      - contacts
    post:
      consumes:
      - application/json
      description: Assigns one or more Roles to one or more Staff Contacts.
      parameters:
      - description: Contact IDs and Role IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RolesToContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Assign Roles to Contacts
      tags:
      - contacts
  /contacts/roles/contacts:
    delete:
      consumes:
      - application/json
      description: Removes one or more Contacts from one or more Roles.
      parameters:
      - description: Role IDs and Contact IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RemoveContactsFromRolesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Contacts from Roles
      tags:
      - contacts
  /contacts/staff:
    get:
      consumes:
      - application/json
      description: Returns a list of Staff Contacts. Supports the same filters as
        GET /contacts, scoped to type=staff.
      parameters:
      - default: id,name,company,type
        description: 'Comma-separated fields to return. Available: id, name, company,
          type, email, phone, fax, address, title, image, lastmodified, logindetails,
          roles, tags, teams, groups, notes'
        in: query
        name: fields
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use email or q+qfields instead. Search by email.
          Use ! for negation'
        in: query
        name: searchemail
        type: string
      - description: Exact name match (firstname + lastname)
        in: query
        name: name
        type: string
      - description: Exact email match
        in: query
        name: email
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - email
        in: query
        name: qfields
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Role IDs (comma-separated)
        in: query
        name: roleid
        type: string
      - description: Group IDs (comma-separated)
        in: query
        name: groupid
        type: string
      - description: Pending status
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Login access filter
        enum:
        - "true"
        - "false"
        in: query
        name: allowlogin
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: integer
      - description: Company ID
        in: query
        name: companyid
        type: integer
      - description: Records modified on or after this date in UTC
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Records modified on or before this date in UTC
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Records with ID >= this value
        in: query
        name: idfrom
        type: integer
      - description: Records with ID <= this value
        in: query
        name: idto
        type: integer
      - description: List of Contact IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: firstname
        description: Sort field
        enum:
        - id
        - firstname
        - lastname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Staff Contacts
      tags:
      - contacts
  /contacts/tags:
    delete:
      consumes:
      - application/json
      description: Removes one or more Tags from one or more Contacts.
      parameters:
      - description: Contact IDs and Tag IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RemoveTagsFromContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Tags from Contacts
      tags:
      - contacts
    post:
      consumes:
      - application/json
      description: Adds one or more Tags to one or more Contacts.
      parameters:
      - description: Contact IDs and Tag IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.TagsToContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Tags to Contacts
      tags:
      - contacts
  /files:
    get:
      consumes:
      - application/json
      description: Returns a list of Files based on the filters specified. The fields
        parameter allows you to choose which data fields to return for each File.
      parameters:
      - default: name,project,item,date,size,link
        description: 'Comma-separated list of fields to return. Available: name, description,
          size, project, projectnumber, projecttitle, item (or task), itemname (or
          taskname), folder, foldername, contactids, date, owner, link, all'
        in: query
        name: fields
        type: string
      - description: Search by file name. Use ! prefix for negation.
        in: query
        name: search
        type: string
      - default: active
        description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project ID or list of Project IDs (comma-separated)
        example: 1,2
        in: query
        name: projectid
        type: string
      - default: all
        description: Filter by item activeworkstate
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Alias for activeworkstate parameter.
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: 'Item (task) ID or list of IDs (comma-separated). Alias: taskid'
        example: 1,2
        in: query
        name: itemid
        type: string
      - description: Alias for itemid parameter.
        example: 1,2
        in: query
        name: taskid
        type: string
      - description: Folder ID or list of Folder IDs (comma-separated)
        example: 1,2
        in: query
        name: folderid
        type: string
      - description: 'Files modified on or after this date (ISO8601 or relative: 12h,
          5d, 2w, 1m)'
        example: "2024-01-18"
        in: query
        name: datefrom
        type: string
      - description: Files modified on or before this date (ISO8601 or relative)
        example: "2024-01-18"
        in: query
        name: dateto
        type: string
      - description: Files with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Files with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of File IDs (comma-separated)
        in: query
        name: id
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - size
        - date
        - itemid
        - taskid
        - folderid
        - projectid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.FileListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Files
      tags:
      - files
  /files/{fileid}:
    delete:
      consumes:
      - application/json
      description: Soft-delete a File by ID.
      parameters:
      - description: File ID
        in: path
        name: fileid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete File
      tags:
      - files
    get:
      consumes:
      - application/json
      description: Returns full details of a single File by ID. Access is scoped by
        the authenticated user's project membership.
      parameters:
      - description: File ID
        in: path
        name: fileid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.FileGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get File
      tags:
      - files
  /files/{fileid}/download:
    get:
      description: 'Downloads the binary content of a File by ID. Returns the raw
        file with Content-Type inferred from the file extension and Content-Disposition
        set to attachment. Note: use curl or an API client to download — Swagger UI
        cannot render binary responses.'
      parameters:
      - description: File ID
        in: path
        name: fileid
        required: true
        type: integer
      produces:
      - application/octet-stream
      responses:
        "200":
          description: File content
          schema:
            type: file
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Download File
      tags:
      - files
  /files/folders:
    get:
      consumes:
      - application/json
      description: Returns a list of Custom Folders based on the specified filters.
        Access is scoped by the authenticated user's project membership (staff see
        all, clients/contractors see their linked projects only). Only returns folders
        of type 'custom'.
      parameters:
      - default: name,project
        description: 'Comma-separated fields to return. Available: name, description,
          type, size, date, owner, contacts, project, item (or task), public'
        in: query
        name: fields
        type: string
      - description: Search by folder name. Use ! for negation
        example: reports
        in: query
        name: search
        type: string
      - default: active
        description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project IDs (comma-separated)
        example: 1,2
        in: query
        name: projectid
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - description: Folders with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Folders with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Folder IDs (comma-separated)
        example: 1,2,3
        in: query
        name: id
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - projectid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.FolderListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Custom Folders
      tags:
      - folders
    post:
      consumes:
      - application/json
      description: Creates a custom folder within a project.
      parameters:
      - description: Folder data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateFolderPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Custom Folder
      tags:
      - folders
  /files/folders/{folderid}:
    delete:
      consumes:
      - application/json
      description: Deletes a custom folder by ID.
      parameters:
      - description: Folder ID
        in: path
        name: folderid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Custom Folder
      tags:
      - folders
    get:
      consumes:
      - application/json
      description: Returns full details of a single Custom Folder by ID. Access is
        scoped by the authenticated user's project membership (staff see all, clients/contractors
        see their linked projects only).
      parameters:
      - description: Folder ID
        in: path
        name: folderid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.FolderGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Custom Folder
      tags:
      - folders
    put:
      consumes:
      - application/json
      description: Updates an existing custom folder.
      parameters:
      - description: Folder ID
        in: path
        name: folderid
        required: true
        type: integer
      - description: Folder update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateFolderPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Custom Folder
      tags:
      - folders
  /files/folders/{folderid}/files:
    post:
      consumes:
      - multipart/form-data
      description: 'Upload a file to a Folder. Send a multipart/form-data request
        with the file in the "file" field. The folder may be a custom folder, project
        root, or task folder — the file is placed in the corresponding location on
        disk. Blocked extensions: exe, msi, ini, bin, bat, cfm, cfc, asp, aspx, php,
        config, vb, java, pl.'
      parameters:
      - description: Folder ID
        in: path
        name: folderid
        required: true
        type: integer
      - description: File to upload
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/handlers.FileUploadResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Upload File to Folder
      tags:
      - folders
  /invoices:
    delete:
      consumes:
      - application/json
      description: Soft deletes one or more invoices by ID.
      parameters:
      - description: Invoice IDs to delete
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkDeleteInvoicesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Delete Invoices
      tags:
      - invoices
    get:
      consumes:
      - application/json
      description: Returns a list of Invoices based on the filters specified. Optionally
        returns subtotals grouped by company, project, status, or time period. Also
        returns the grand totals across all returned invoices.
      parameters:
      - default: number,title,company,status,totals,projectid,invoiceddate,duedate
        description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>number</b> - Invoice number/reference code</li><li><b>title</b>
          - Invoice title</li><li><b>status</b> - Invoice status (draft, submitted,
          authorised, paid, voided, deleted)</li><li><b>description</b> - Invoice
          description (plain text, HTML stripped)</li><li><b>company</b> - Client
          company ID and name</li><li><b>project</b> - Associated project IDs, titles,
          and numbers as a comma-delimited list</li><li><b>projectid</b> - Associated
          project IDs only (comma-separated if multiple)</li><li><b>dates</b> - All
          date fields: invoiceddate, duedate, paiddate</li><li><b>invoiceddate</b>
          - Invoice issue date (yyyy-mm-dd)</li><li><b>duedate</b> - Payment due date
          (yyyy-mm-dd)</li><li><b>paiddate</b> - Date payment was received (yyyy-mm-dd)</li><li><b>emaileddate</b>
          - Date invoice was emailed (yyyy-mm-dd)</li><li><b>emailedto</b> - Email
          address the invoice was sent to</li><li><b>emailedtoclient</b> - Whether
          the invoice has been emailed to the client (boolean)</li><li><b>invoicedby</b>
          - Full name of the contact who created the invoice</li><li><b>totals</b>
          - Financial totals: subtotal, taxtotal, and grandtotal (all decimal, 2dp)</li><li><b>taxable</b>
          - Whether the invoice is taxable (boolean)</li><li><b>taxrate</b> - Tax
          rate as a percentage (decimal, e.g. 15.0)</li><li><b>purchaseordernumber</b>
          - Client purchase order reference number</li><li><b>showcostbreakdown</b>
          - Whether cost breakdown is displayed (boolean)</li><li><b>showitemdescription</b>
          - Whether item descriptions are shown (boolean)</li><li><b>showphases</b>
          - Whether phases are shown (boolean)</li><li><b>customfield</b> - Custom
          field name and value pair</li><li><b>paid</b> - Whether the invoice has
          been paid (boolean)</li><li><b>activeworkstageid</b> - Active work stage
          ID</li><li><b>clientcontactname</b> - Client contact name on the invoice</li><li><b>invoicetermid</b>
          - Invoice payment term ID</li><li><b>paymentterms</b> - Payment terms text
          (returned together with invoicetermid)</li><li><b>pagetitle</b> - Page/PDF
          title of the invoice</li><li><b>address</b> - All address fields: address1,
          address2, address3, city, state, zipcode, country</li><li><b>budget</b>
          - Budget fields: budget, budgetTax, budgetType</li><li><b>billamount</b>
          - Bill amount fields: billAmount, billAmountTax, billType</li><li><b>estbillamount</b>
          - Estimated bill amount (sensitive)</li><li><b>estbillamounttax</b> - Estimated
          bill amount including tax (sensitive)</li><li><b>itemsdiscount</b> - Items
          discount value (sensitive)</li><li><b>timebillable</b> - Billable time in
          minutes (sensitive)</li><li><b>template</b> - Whether this invoice is a
          template (boolean)</li><li><b>lastmodified</b> - Last modified date in ISO8601
          format (UTC)</li><li><b>all</b> - Returns all available scalar fields</li></ul><b>Sub-entity
          fields</b> (heavy — NOT included by <b>all</b>, must be named explicitly):
          <b>phases</b> - invoice phases and their line items. Use e.g. <i>fields=all,phases</i>
          or <i>fields=phases</i>.'
        in: query
        name: fields
        type: string
      - description: 'Deprecated: use number, title, or q+qfields instead. Search
          by number or title. Use ! for negation.'
        in: query
        name: search
        type: string
      - description: 'Deprecated: use number or q+qfields instead. Search by invoice
          number. Supports ! for negation.'
        in: query
        name: searchnumber
        type: string
      - description: 'Deprecated: use title or q+qfields instead. Search by invoice
          title. Supports ! for negation.'
        in: query
        name: searchtitle
        type: string
      - description: Exact number match
        in: query
        name: number
        type: string
      - description: Exact title match
        in: query
        name: title
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - number
        - title
        in: query
        name: qfields
        type: string
      - description: 'Status (activeworkstate). Alias: activeworkstate.'
        enum:
        - draft
        - submitted
        - authorised
        - paid
        - voided
        - deleted
        - all
        - unpaid
        in: query
        name: status
        type: string
      - description: Alias for status.
        enum:
        - draft
        - submitted
        - authorised
        - paid
        - voided
        - deleted
        - all
        - unpaid
        in: query
        name: activeworkstate
        type: string
      - description: Filter by taxable status
        enum:
        - "true"
        - "false"
        - all
        in: query
        name: taxable
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Project manager Contact IDs (comma-separated)
        in: query
        name: managerid
        type: string
      - description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project category IDs (comma-separated)
        in: query
        name: projectcategoryid
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: Company IDs (comma-separated)
        in: query
        name: companyid
        type: string
      - description: Filter invoices by active work stage ID
        in: query
        name: workstageid
        type: string
      - description: 'Invoiced date from (ISO8601 or relative: 12h, 5d, 2w, 1m)'
        in: query
        name: invoiceddatefrom
        type: string
      - description: Invoiced date to (ISO8601 or relative)
        in: query
        name: invoiceddateto
        type: string
      - description: Due date from (ISO8601 or relative)
        in: query
        name: duedatefrom
        type: string
      - description: Due date to (ISO8601 or relative)
        in: query
        name: duedateto
        type: string
      - description: Paid date from (ISO8601 or relative)
        in: query
        name: paiddatefrom
        type: string
      - description: Paid date to (ISO8601 or relative)
        in: query
        name: paiddateto
        type: string
      - description: Grand total minimum
        in: query
        name: grandtotalfrom
        type: string
      - description: Grand total maximum
        in: query
        name: grandtotalto
        type: string
      - description: Group results by. Returns subtotals per group.
        enum:
        - company
        - project
        - status
        - day
        - week
        - month
        - year
        in: query
        name: subtotals
        type: string
      - description: Date field for subtotals grouping
        enum:
        - invoiced
        - due
        - paid
        in: query
        name: subtotalsdateoption
        type: string
      - description: Invoices modified on or after this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Invoices modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Invoices with ID greater than or equal to this value
        in: query
        name: idfrom
        type: string
      - description: Invoices with ID less than or equal to this value
        in: query
        name: idto
        type: string
      - description: List of Invoice IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - invoiceddate
        - duedate
        - companyname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoices
      tags:
      - invoices
    post:
      consumes:
      - application/json
      description: Creates a new invoice.
      parameters:
      - description: Invoice data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateInvoicePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Invoice
      tags:
      - invoices
  /invoices/{invoiceid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes an invoice by setting activeworkstate to 'deleted'.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Invoice
      tags:
      - invoices
    get:
      consumes:
      - application/json
      description: 'View a single Invoice. Returns detailed information including
        phases and line items. IMPORTANT: For Task/Staff Rate Lines, the ''rate''
        value is cost/hour, the ''time'' value is the time in minutes.'
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice
      tags:
      - invoices
    put:
      consumes:
      - application/json
      description: Updates an existing invoice. Only provide the fields you want to
        update.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Invoice update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateInvoicePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Invoice
      tags:
      - invoices
  /invoices/{invoiceid}/clone:
    post:
      consumes:
      - application/json
      description: Clones an existing invoice.
      parameters:
      - description: Invoice ID to clone
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Clone options
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CloneQuoteInvoiceRequest'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Clone Invoice
      tags:
      - invoices
  /invoices/{invoiceid}/items:
    get:
      consumes:
      - application/json
      description: Returns a list of line items for an invoice. Supports field selection,
        filtering, sorting and pagination.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - default: id,name,itemcollectionid,parentid,itemtypeid,activeworkstate,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by item name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Filter to items within a specific phase (itemcollectionid)
        in: query
        name: phaseid
        type: integer
      - description: Filter by parent item ID (0 = top-level only)
        in: query
        name: parentid
        type: integer
      - description: Filter by item type ID
        in: query
        name: itemtypeid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Items
      tags:
      - invoices
    post:
      consumes:
      - application/json
      description: Creates one or more line items within an invoice phase.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Item data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.InvoiceItemCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Invoice Items
      tags:
      - invoices
  /invoices/{invoiceid}/items/{itemid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes an invoice line item.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Invoice Item
      tags:
      - invoices
    get:
      consumes:
      - application/json
      description: Returns full details of a single invoice line item by ID.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceItemGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Item
      tags:
      - invoices
    put:
      consumes:
      - application/json
      description: Updates an existing invoice line item.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Item update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.InvoiceItemUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Invoice Item
      tags:
      - invoices
  /invoices/{invoiceid}/items/{itemid}/workstages:
    get:
      consumes:
      - application/json
      description: Returns the workstage history for an invoice line item.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - default: setdatetime
        description: Sort field
        enum:
        - setdatetime
        - id
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ItemWorkStageHistoryListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Item Workstage History
      tags:
      - invoices
  /invoices/{invoiceid}/order:
    put:
      consumes:
      - application/json
      description: Moves an invoice before or after another invoice using sortorder.
        Provide exactly one of placeafterid or placebeforeid.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Order placement
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateInvoiceOrderRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Reorder Invoice
      tags:
      - invoices
  /invoices/{invoiceid}/phases:
    get:
      consumes:
      - application/json
      description: Returns a list of phases (item collections) for an invoice.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - default: id,name,invoiceid,parentid,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by phase name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Filter to phases with a specific parent phase ID (0 = top-level
          only)
        in: query
        name: parentid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoicePhaseListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Phases
      tags:
      - invoices
    post:
      consumes:
      - application/json
      description: Creates one or more phases (item collections) within an invoice.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Phase data (single object or array)
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateInvoicePhasePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Invoice Phases
      tags:
      - invoices
  /invoices/{invoiceid}/phases/{phaseid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes an invoice phase and its associated items.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Invoice Phase
      tags:
      - invoices
    get:
      consumes:
      - application/json
      description: Returns full details of a single invoice phase (item collection)
        by ID.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoicePhaseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Phase
      tags:
      - invoices
    put:
      consumes:
      - application/json
      description: Updates an existing invoice phase.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      - description: Phase update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateInvoicePhasePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Invoice Phase
      tags:
      - invoices
  /invoices/{invoiceid}/workstage:
    put:
      consumes:
      - application/json
      description: Sets the active work stage for an invoice.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - description: Work stage
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateInvoiceWorkStageRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Invoice Work Stage
      tags:
      - invoices
  /invoices/{invoiceid}/workstages:
    get:
      consumes:
      - application/json
      description: Returns the workstage history for an invoice.
      parameters:
      - description: Invoice ID
        in: path
        name: invoiceid
        required: true
        type: integer
      - default: setdatetime
        description: Sort field
        enum:
        - setdatetime
        - id
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceWorkStageHistoryListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Workstage History
      tags:
      - invoices
  /invoices/items:
    get:
      consumes:
      - application/json
      description: Returns a list of all invoice line items across all invoices, based
        on the filters specified.
      parameters:
      - default: id,name,itemcollectionid,parentid,itemtypeid,activeworkstate,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by item name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Invoice ID or list of Invoice IDs (comma-separated)
        in: query
        name: invoiceid
        type: string
      - description: Filter to items within a specific phase (itemcollectionid)
        in: query
        name: phaseid
        type: integer
      - description: Filter by parent item ID (0 = top-level only)
        in: query
        name: parentid
        type: integer
      - description: Filter by item type ID
        in: query
        name: itemtypeid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Items
      tags:
      - invoices
    post:
      consumes:
      - application/json
      description: Creates one or more invoice line items. The invoiceid must be provided
        in the request body.
      parameters:
      - description: Item data (single object or array)
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.InvoiceItemCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Invoice Items
      tags:
      - invoices
    put:
      consumes:
      - application/json
      description: Updates one or more invoice items by ID. All fields except ids
        are optional — only provided fields are updated.
      parameters:
      - description: Item IDs and fields to update
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdateItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Invoice Items
      tags:
      - invoices
  /invoices/items/{itemid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes an invoice line item by ID, without requiring the
        invoice ID.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Invoice Item
      tags:
      - invoices
    get:
      consumes:
      - application/json
      description: Returns full details of a single invoice line item by ID, without
        requiring the invoice ID.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceItemGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Item
      tags:
      - invoices
    put:
      consumes:
      - application/json
      description: Updates an existing invoice line item by ID, without requiring
        the invoice ID.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Item update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.InvoiceItemUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Invoice Item
      tags:
      - invoices
  /invoices/items/{itemid}/order:
    put:
      consumes:
      - application/json
      description: Moves an invoice item before or after another item using sortorder.
        Provide exactly one of placeafterid or placebeforeid.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Order placement
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateInvoiceItemOrderRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Reorder Invoice Item
      tags:
      - invoices
  /invoices/overdue:
    get:
      consumes:
      - application/json
      description: 'Returns invoices that are past their due date and have not been
        paid (status: submitted or authorised). Supports the same field selection,
        sorting, and pagination as GET /invoices.'
      parameters:
      - default: number,title,company,status,totals,projectid,invoiceddate,duedate
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by number or title. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Search by invoice number. Supports ! for negation.
        in: query
        name: searchnumber
        type: string
      - description: Search by invoice title. Supports ! for negation.
        in: query
        name: searchtitle
        type: string
      - description: Filter by taxable status
        enum:
        - "true"
        - "false"
        - all
        in: query
        name: taxable
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Project manager Contact IDs (comma-separated)
        in: query
        name: managerid
        type: string
      - description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project category IDs (comma-separated)
        in: query
        name: projectcategoryid
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: Company IDs (comma-separated)
        in: query
        name: companyid
        type: string
      - description: 'Invoiced date from (ISO8601 or relative: 12h, 5d, 2w, 1m)'
        in: query
        name: invoiceddatefrom
        type: string
      - description: Invoiced date to (ISO8601 or relative)
        in: query
        name: invoiceddateto
        type: string
      - description: Due date from (ISO8601 or relative)
        in: query
        name: duedatefrom
        type: string
      - description: Grand total minimum
        in: query
        name: grandtotalfrom
        type: string
      - description: Grand total maximum
        in: query
        name: grandtotalto
        type: string
      - description: Last modified UTC from (ISO8601 or relative)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified UTC to (ISO8601 or relative)
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Invoice ID range from
        in: query
        name: idfrom
        type: string
      - description: Invoice ID range to
        in: query
        name: idto
        type: string
      - description: List of Invoice IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: duedate
        description: Sort field
        enum:
        - id
        - number
        - title
        - invoiceddate
        - duedate
        - companyname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get overdue invoices
      tags:
      - invoices
  /invoices/phases:
    get:
      consumes:
      - application/json
      description: Returns phases (item collections) across all invoices. Optionally
        filter by one or more invoice IDs.
      parameters:
      - default: id,name,invoiceid,parentid,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by phase name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Invoice ID or comma-separated list of Invoice IDs to filter by
        example: 1,2
        in: query
        name: invoiceid
        type: string
      - description: Filter to phases with a specific parent phase ID (0 = top-level
          only)
        in: query
        name: parentid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoicePhaseListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Phases
      tags:
      - invoices
    post:
      consumes:
      - application/json
      description: Creates one or more invoice phases (item collections). The invoiceid
        must be included in the request body.
      parameters:
      - description: Phase data (single object or array)
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateInvoicePhasePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Invoice Phases
      tags:
      - invoices
    put:
      consumes:
      - application/json
      description: Updates one or more invoice phases by ID. All fields except ids
        are optional.
      parameters:
      - description: Phase IDs and fields to update
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdatePhasesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Invoice Phases
      tags:
      - invoices
  /invoices/phases/{phaseid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes an invoice phase by ID.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Invoice Phase
      tags:
      - invoices
    get:
      consumes:
      - application/json
      description: Returns full details of a single invoice phase by ID.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoicePhaseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Phase
      tags:
      - invoices
    put:
      consumes:
      - application/json
      description: Updates an existing invoice phase by ID.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      - description: Phase update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateInvoicePhasePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Invoice Phase
      tags:
      - invoices
  /invoices/phases/adjustdates:
    put:
      consumes:
      - application/json
      description: Shifts item dates within one or more invoice phases by a number
        of days. Negative values shift backwards.
      parameters:
      - description: Phase IDs and day offset
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkAdjustPhaseDatesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Adjust Invoice Phase Dates
      tags:
      - invoices
  /me:
    get:
      consumes:
      - application/json
      description: Returns details of the Contact making the request (the authenticated
        user). Requires JWT authentication — API key auth has no user context.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.MeGetResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      summary: Get Contact Information
      tags:
      - me
  /messages:
    get:
      consumes:
      - application/json
      description: 'Returns a list of Messages based on the filters specified. The
        fields parameter allows you to choose which data fields to return for each
        Message. IMPORTANT: We recommend using the datefrom option to return only
        messages added in the timeframe you require.'
      parameters:
      - default: subject,content,originalmessageid,project,item,date,author,contacts,public,files
        description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>subject</b> - Message subject</li><li><b>content</b> - Full message
          body (HTML stripped)</li><li><b>originalmessageid</b> - Parent message ID
          (0 if this started the discussion)</li><li><b>project</b> - Project ID,
          number, and title</li><li><b>item</b> (or <b>task</b>) - Item ID and name</li><li><b>itemid</b>
          (or <b>taskid</b>) - Item ID only</li><li><b>itemname</b> (or <b>taskname</b>)
          - Item name only</li><li><b>date</b> - Message date (ISO8601)</li><li><b>author</b>
          - All author fields (id, type, name, email, image)</li><li><b>authorid</b>
          - Author contact ID</li><li><b>authortype</b> - Author contact type</li><li><b>authorname</b>
          - Author display name</li><li><b>authoremail</b> - Author email address</li><li><b>authorimage</b>
          - Author avatar image URL</li><li><b>contacts</b> - Recipient contact IDs</li><li><b>public</b>
          - Whether message is public</li><li><b>files</b> - File IDs and files-enabled
          flag</li><li><b>replycount</b> - Number of replies</li><li><b>all</b> -
          All fields</li></ul>'
        in: query
        name: fields
        type: string
      - description: Search by subject. <ul><li><b>string</b> - Messages where subject
          contains string</li><li><b>!string</b> - Messages where subject does NOT
          contain string</li></ul>
        in: query
        name: search
        type: string
      - description: Filter by contact. Comma-separated Contact IDs, 'me', or 'all'
        example: 1,2
        in: query
        name: contacts
        type: string
      - default: active
        description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project ID or list of Project IDs (comma-separated)
        example: 1,2
        in: query
        name: projectid
        type: string
      - default: all
        description: Filter by item activeworkstate
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Alias for activeworkstate parameter.
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: 'Item (task) ID or list of IDs (comma-separated). Alias: taskid'
        example: 1,2
        in: query
        name: itemid
        type: string
      - description: Alias for itemid parameter.
        example: 1,2
        in: query
        name: taskid
        type: string
      - description: Original Message ID - returns messages in the discussion started
          by this message
        example: "1"
        in: query
        name: originalmessageid
        type: string
      - description: 'Messages added on or after this date (ISO8601 or relative: 12h,
          5d, 2w, 1m)'
        example: "2024-01-18"
        in: query
        name: datefrom
        type: string
      - description: Messages added on or before this date (ISO8601 or relative)
        example: "2024-01-18"
        in: query
        name: dateto
        type: string
      - description: Messages with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Messages with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Message IDs (comma-separated)
        in: query
        name: id
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - date
        - originalmessageid
        - projectid
        - itemid
        - taskid
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.MessageListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Messages
      tags:
      - messages
    post:
      consumes:
      - application/json
      description: Add a Message to a project or item discussion, or reply to an existing
        message. For new discussions, provide subject, content, contacts, and either
        projectid or itemid. For replies, provide content and originalmessageid.
      parameters:
      - description: Message data
        in: body
        name: message
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateMessagePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Message
      tags:
      - messages
  /messages/{messageid}:
    delete:
      consumes:
      - application/json
      description: Deletes a Message.
      parameters:
      - description: Message ID
        in: path
        name: messageid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Message
      tags:
      - messages
    get:
      consumes:
      - application/json
      description: Returns details of a single Message including all replies. The
        projectcontacts parameter (staff only) includes the list of contacts assigned
        to the message's project, for use when composing replies.
      parameters:
      - description: Message ID
        in: path
        name: messageid
        required: true
        type: integer
      - default: "false"
        description: Return project contacts (staff only)
        enum:
        - "true"
        - "false"
        in: query
        name: projectcontacts
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.MessageGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Message
      tags:
      - messages
    put:
      consumes:
      - application/json
      description: Updates a Message.
      parameters:
      - description: Message ID
        in: path
        name: messageid
        required: true
        type: integer
      - description: Message data to update
        in: body
        name: message
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateMessagePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Message
      tags:
      - messages
  /messages/contacts:
    delete:
      consumes:
      - application/json
      description: 'Removes one or more Contacts from one or more Messages. Note:
        you cannot remove a recipient who has replied to the discussion.'
      parameters:
      - description: Message IDs and Contact IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.MessageContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Contacts from Messages
      tags:
      - messages
    post:
      consumes:
      - application/json
      description: Adds one or more Contacts to one or more Messages.
      parameters:
      - description: Message IDs and Contact IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.MessageContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Contacts to Messages
      tags:
      - messages
  /projectnotes:
    get:
      consumes:
      - application/json
      description: Returns a list of Project Notes based on the filters specified.
        The fields parameter allows you to choose which data fields to return for
        each Project Note.
      parameters:
      - default: content,title
        description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>company</b> - Company ID and name</li><li><b>content</b> - Note
          body text</li><li><b>lastmodified</b> - Last modified date (UTC)</li><li><b>project</b>
          - Project ID, number, and title</li><li><b>title</b> - Note title</li></ul>'
        in: query
        name: fields
        type: string
      - description: 'Search by title. Use ! for negation. Example: website or !layout'
        in: query
        name: search
        type: string
      - description: 'Project Category ID or comma-separated list of IDs. Example:
          1,2'
        in: query
        name: categoryid
        type: string
      - default: active
        description: Project completion status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: 'Project ID or comma-separated list of IDs. Example: 1,2'
        in: query
        name: projectid
        type: string
      - description: 'Company ID or comma-separated list of IDs. Example: 1,2,3'
        in: query
        name: companyid
        type: string
      - description: 'Division ID (Advanced plan only). Example: 1'
        in: query
        name: divisionid
        type: string
      - description: Notes with ID greater than or equal to this value
        in: query
        name: idfrom
        type: string
      - description: Notes with ID less than or equal to this value
        in: query
        name: idto
        type: string
      - description: 'Comma-separated list of Note IDs. Example: 1,2,3,4'
        in: query
        name: id
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - projectid
        - title
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: 'Page number (must be used with pagesize). Example: 2'
        in: query
        name: pagenumber
        type: integer
      - description: 'Page size (must be used with pagenumber). Example: 10'
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectNoteListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Notes
      tags:
      - projectnotes
    post:
      consumes:
      - application/json
      description: Creates a new Project Note.
      parameters:
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.ProjectNoteCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Note
      tags:
      - projectnotes
  /projectnotes/{noteid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Project Note.
      parameters:
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Note
      tags:
      - projectnotes
    get:
      consumes:
      - application/json
      description: Returns details of a single Project Note.
      parameters:
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectnoteGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Note
      tags:
      - projectnotes
    put:
      consumes:
      - application/json
      description: Updates a Project Note.
      parameters:
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.ProjectNoteUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Note
      tags:
      - projectnotes
  /projects:
    delete:
      consumes:
      - application/json
      description: Soft deletes one or more projects by ID.
      parameters:
      - description: Project IDs to delete
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkDeleteProjectsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Delete Projects
      tags:
      - projects
    get:
      consumes:
      - application/json
      description: Returns a list of Projects based on the filters specified.
      parameters:
      - description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>title</b> - Project title</li><li><b>number</b> - Project number/reference
          code</li><li><b>description</b> - Project description (HTML)</li><li><b>privatenotes</b>
          - Private notes as HTML (staff only)</li><li><b>sortorder</b> - Sort position</li><li><b>deleted</b>
          - Deleted flag</li><li><b>createdate</b> - Date project was created (yyyy-mm-dd)</li><li><b>activeworkstate</b>
          - Work state (active, complete, deleted)</li><li><b>template</b> - Whether
          the project is a template (boolean)</li><li><b>isclassic</b> - Whether the
          project uses classic mode (boolean)</li><li><b>status</b> - Returns activeworkstate</li><li><b>type</b>
          - Client type: internal or external (Advanced plan only)</li><li><b>workstage</b>
          - Work stage ID and name</li><li><b>workstate</b> - Returns activeworkstate</li><li><b>company</b>
          - Client company ID and name</li><li><b>internalclientcontactid</b> - Internal
          client contact ID (Advanced plan only)</li><li><b>internalclientteamid</b>
          - Internal client team ID (Advanced plan only)</li><li><b>internalclientteamname</b>
          - Internal client team name (Advanced plan only)</li><li><b>internalclientgroupid</b>
          - Internal client group ID (Advanced plan only)</li><li><b>internalclientgroupname</b>
          - Internal client group name (Advanced plan only)</li><li><b>manager</b>
          - Project manager contact ID and full name</li><li><b>category</b> - Project
          category ID and name</li><li><b>priority</b> - Priority level (integer:
          1=Very High, 2=High, 3=Medium, 4=Low, 5=Very Low)</li><li><b>contacts</b>
          - Returns clients, contractors, and staff as JSON arrays of contact objects
          [{id, firstname, lastname}]</li><li><b>tags</b> - Project tags as a JSON
          array [{id, name, color}]</li><li><b>customfields</b> - Custom field options
          (Advanced plan only)</li><li><b>team</b> - Team ID and name (Advanced plan
          only)</li><li><b>group</b> - Group ID and name (Advanced plan only)</li><li><b>staffid</b>
          - Staff contact IDs (comma-separated)</li><li><b>contractorid</b> - Contractor
          contact IDs (comma-separated)</li><li><b>clientid</b> - Client contact IDs
          (comma-separated)</li><li><b>contactid</b> - All contact IDs (comma-separated)</li><li><b>tagid</b>
          - Tag IDs (comma-separated)</li><li><b>icalcontactid</b> - iCal contact
          IDs (comma-separated)</li><li><b>integrationfolderid</b> - Integration folder
          IDs (comma-separated)</li><li><b>customfieldoptionid</b> - Custom field
          option IDs (comma-separated)</li><li><b>dates</b> - All date fields: startdate,
          duedate, completedate</li><li><b>startdate</b> - Start date (yyyy-mm-dd)</li><li><b>duedate</b>
          - Due date (yyyy-mm-dd)</li><li><b>completedate</b> - Completion date (yyyy-mm-dd)</li><li><b>lastmodified</b>
          - Last modified date in ISO8601 format (UTC)</li><li><b>clientaccess</b>
          - Client access enabled (boolean)</li><li><b>clientviewalltasks</b> - Client
          can view all tasks (boolean)</li><li><b>clientviewtime</b> - Client can
          view time (boolean)</li><li><b>staffviewalltasks</b> - Staff can view all
          tasks (boolean)</li><li><b>purchaseordernumber</b> - Client purchase order
          reference</li><li><b>notification</b> - Notifications enabled (boolean)</li><li><b>messagessortorder</b>
          - Messages sort order</li><li><b>pdmodulesrightcontainer</b> - Right container
          module config</li><li><b>pdmodulesmaincontainer</b> - Main container module
          config</li><li><b>timeallocated</b> - Total time allocated in decimal hours</li><li><b>timetracked</b>
          - Total time spent/tracked in decimal hours</li><li><b>timebillable</b>
          - Total billable time in decimal hours</li><li><b>budget</b> - Project budget
          including tax (decimal, 2dp)</li><li><b>burn</b> - Financial burn (decimal,
          2dp)</li><li><b>billtotal</b> - Total bill amount including tax (decimal,
          2dp)</li><li><b>invoicetotal</b> - Total invoiced amount including tax (decimal,
          2dp)</li><li><b>paidamount</b> - Total paid amount including tax (decimal,
          2dp)</li><li><b>invoiced</b> - Invoiced status (boolean)</li><li><b>percentcomplete</b>
          - Percentage of tasks completed (integer 0-100, heading tasks excluded)</li><li><b>scoring</b>
          - Scoring/aggregate fields: storypoints, itemscompleted, itemsactive, itemstartdate,
          itemduedate</li><li><b>discount</b> - Discount fields: itemsdiscount</li><li><b>units</b>
          - Unit/pricing fields: inunittotal, outunittotal, costratetype, chargeratetype</li><li><b>budgetdetail</b>
          - Budget detail fields: budgettype, budgettax</li><li><b>billingdetail</b>
          - Billing detail fields: billtype, billamount, billamounttax</li><li><b>estimated</b>
          - Estimated cost/revenue: estinlabour, estintotal, estintotaltax, estoutlabour,
          estbillamount, estbillamounttax</li><li><b>actual</b> - Actual cost/revenue:
          actualinlabour, actualintotal, actualintotaltax, actualoutlabour</li><li><b>projected</b>
          - Projected values: projectedtimemanual, projectedtimespent, projectedbillamount,
          projectedbillamounttax</li><li><b>profit</b> - Profit/margin fields: estprofit,
          projectedprofit, estgrossmargin, projectedgrossmargin</li><li><b>invoiceddetail</b>
          - Invoiced detail fields: invoicedamount, invoicedamounttax, paidamounttax</li><li><b>all</b>
          - Returns all available scalar fields</li></ul><b>Sub-entity fields</b>
          (heavy — NOT included by <b>all</b>, must be named explicitly): <b>phases</b>
          - project phases and their tasks; <b>timerecords</b> - time records; <b>messages</b>
          - messages; <b>files</b> - files; <b>folders</b> - folders; <b>invoices</b>
          - linked invoices; <b>workstages</b> - project workstage history; <b>bookmarks</b>
          - bookmarks; <b>projectnotes</b> - project notes. Use e.g. <i>fields=all,phases</i>
          or <i>fields=phases,timerecords</i>.'
        example: '"title,number,company,startdate,duedate"'
        in: query
        name: fields
        type: string
      - description: '[Deprecated: use title instead] Search. <ul><li><b>string</b>
          - Projects where Number or Title contains string<br>Example: website</li><li><b>!string</b>
          - Projects where Number and Title do not contain string<br>Example: !layout</li></ul>'
        in: query
        name: search
        type: string
      - description: '[Deprecated: use number instead] Search Number. <ul><li><b>string</b>
          - Projects where Number contains string<br>Example: PRJ-2024</li><li><b>!string</b>
          - Projects where Number does not contain string<br>Example: !TEST</li></ul>'
        in: query
        name: searchnumber
        type: string
      - description: 'Filter by exact Title. Example: Website Redesign'
        in: query
        name: title
        type: string
      - description: 'Filter by exact Number. Example: PRJ-001'
        in: query
        name: number
        type: string
      - description: 'Fuzzy search term. Searches the fields specified by qfields
          (default: number and title). Example: website'
        in: query
        name: q
        type: string
      - description: 'Comma-separated list of fields to apply fuzzy search (q) to.
          Allowed values: number, title. Defaults to both when q is set. Example:
          number,title'
        in: query
        name: qfields
        type: string
      - default: active
        description: Status (activeworkstate). <ul><li><b>active</b> - Active Projects</li><li><b>complete</b>
          - Completed Projects</li><li><b>deleted</b> - Deleted Projects</li><li><b>all</b>
          - All Projects (excludes deleted)</li></ul>
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Alias for status parameter.
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: 'Company ID or List of Company IDs. <ul><li><b>companyid/s</b>
          - Projects in specified Company/ies<br>Example: 1,2,3</li><li><b>!companyid/s</b>
          - Projects NOT for specified Company/ies</li></ul>'
        in: query
        name: companyid
        type: string
      - default: all
        description: 'Manager. <ul><li><b>managerid/s</b> - Contact ID or List of
          Contact IDs - Projects Managed by any of the specified Contact/s<br>Example:
          1,2</li><li><b>!managerid/s</b> - Contact ID or List of Contact IDs - Projects
          NOT Managed by any of the specified Contact/s<br>Example: !1,2</li><li><b>me</b>
          - Projects Managed by Contact making request</li><li><b>all</b> - All Projects</li></ul>'
        in: query
        name: managerid
        type: string
      - default: all
        description: 'Contacts. <ul><li><b>contactid/s</b> - Contact ID or List of
          Contact IDs - Projects assigned to ANY/ALL specified Contact/s (see contactsmode
          parameter)<br>Example: 1,2</li><li><b>!contactid/s</b> - Contact ID or List
          of Contact IDs - Projects NOT assigned to ANY/ALL specified Contact/s (see
          contactsmode parameter)<br>Example: !1,2</li><li><b>me</b> - Projects assigned
          to Contact making request</li><li><b>all</b> - All Projects</li></ul>'
        in: query
        name: contacts
        type: string
      - default: any
        description: Mode used for the contacts parameter. <ul><li><b>any</b> - Projects
          assigned to ANY of the specified contacts</li><li><b>all</b> - Projects
          assigned to ALL of the specified contacts</li></ul>
        enum:
        - any
        - all
        in: query
        name: contactsmode
        type: string
      - description: 'Team (Advanced plan only). <ul><li><b>teamid/s</b> - Team ID
          or List of Team IDs - Projects Managed by any of the specified Team/s<br>Example:
          1,2</li><li><b>!teamid/s</b> - Team ID or List of Team IDs - Projects NOT
          Managed by any of the specified Team/s<br>Example: !1,2</li></ul>'
        in: query
        name: teamid
        type: string
      - description: 'Group (Advanced plan only). <ul><li><b>groupid/s</b> - Group
          ID or List of Group IDs - Projects Managed by any of the specified Group/s<br>Example:
          1,2</li><li><b>!groupid/s</b> - Group ID or List of Group IDs - Projects
          NOT Managed by any of the specified Group/s<br>Example: !1,2</li></ul>'
        in: query
        name: groupid
        type: string
      - description: 'Category ID or List of Category IDs. <ul><li><b>categoryid/s</b>
          - Projects in specified Category/ies<br>Example: 1,2,3</li><li><b>!categoryid/s</b>
          - Projects NOT in specified Category/ies<br>Example: !1,2,3</li></ul>'
        in: query
        name: categoryid
        type: string
      - description: 'Tag ID or List of Tag IDs. <ul><li><b>tagid/s</b> - Projects
          with specified Tag/s<br>Example: 1,2,3</li><li><b>!tagid/s</b> - Projects
          without specified Tag/s<br>Example: !1,2,3</li></ul>'
        in: query
        name: tagid
        type: string
      - description: 'Priority or List of Priorities (1-5 representing Very High-Very
          Low). <ul><li><b>priority/ies</b> - Projects with specified Priority/ies<br>Example:
          1,2</li><li><b>!priority/ies</b> - Projects NOT with specified Priority/ies<br>Example:
          !4,5</li></ul>'
        in: query
        name: priority
        type: string
      - description: 'Workstage ID or List of Workstage IDs . <ul><li><b>workstageid/s</b>
          - Projects with specified Workstages<br>Example: 1,2</li><li><b>!workstageid/s</b>
          - Projects without specified Workstages<br>Example: !1,2</li></ul>'
        in: query
        name: workstageid
        type: string
      - description: 'Projects starting on or after this date. <ul><li><b>Specific
          date</b> - Date in yyyy-mm-dd format<br>Example: 2014-01-18</li><li><b>Relative
          date</b> - +/-Xd/w/m/y<br>Examples: -3w - 3 weeks ago OR +1m - 1 month ahead</li></ul>'
        in: query
        name: startdatefrom
        type: string
      - description: 'Projects starting on or before this date. <ul><li><b>Specific
          date</b> - Date in yyyy-mm-dd format<br>Example: 2014-01-18</li><li><b>Relative
          date</b> - +/-Xd/w/m/y<br>Examples: -3w - 3 weeks ago OR +1m - 1 month ahead</li></ul>'
        in: query
        name: startdateto
        type: string
      - description: 'Projects due on or after this date. <ul><li><b>Specific date</b>
          - Date in yyyy-mm-dd format<br>Example: 2014-01-18</li><li><b>Relative date</b>
          - +/-Xd/w/m/y<br>Examples: -3w - 3 weeks ago OR +1m - 1 month ahead</li></ul>'
        in: query
        name: duedatefrom
        type: string
      - description: 'Projects due on or before this date. <ul><li><b>Specific date</b>
          - Date in yyyy-mm-dd format<br>Example: 2014-01-18</li><li><b>Relative date</b>
          - +/-Xd/w/m/y<br>Examples: -3w - 3 weeks ago OR +1m - 1 month ahead</li></ul>'
        in: query
        name: duedateto
        type: string
      - description: 'Projects completed on or after this date. <ul><li><b>Specific
          date</b> - Date in yyyy-mm-dd format<br>Example: 2014-01-18</li><li><b>Relative
          date</b> - +/-Xd/w/m/y<br>Examples: -3w - 3 weeks ago OR +1m - 1 month ahead</li></ul>'
        in: query
        name: completedatefrom
        type: string
      - description: 'Projects completed on or before this date. <ul><li><b>Specific
          date</b> - Date in yyyy-mm-dd format<br>Example: 2014-01-18</li><li><b>Relative
          date</b> - +/-Xd/w/m/y<br>Examples: -3w - 3 weeks ago OR +1m - 1 month ahead</li></ul>'
        in: query
        name: completedateto
        type: string
      - description: Projects added/edited on or after this date (UTC). ISO8601 or
          relative (12h, 5d, 2w, 1m)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Projects added/edited on or before this date (UTC). ISO8601 or
          relative (12h, 5d, 2w, 1m)
        in: query
        name: lastmodifiedutcto
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - startdate
        - duedate
        - completedate
        - companyname
        - categoryname
        - priority
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Projects
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Creates a new external project with a company as the client. This
        endpoint now proxies to POST /projects/external.
      parameters:
      - description: External project data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateExternalProjectPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Projects
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates one or more projects by ID. All fields except ids are optional
        — only provided fields are updated.
      parameters:
      - description: Project IDs and fields to update
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdateProjectsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Projects
      tags:
      - projects
  /projects/{projectid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project
      tags:
      - projects
    get:
      consumes:
      - application/json
      description: Returns details of a single Project. By default returns all scalar
        fields. Add sub-entity names to fields to include them (e.g. fields=all,phases).
        Sub-entities are never included by "all" — they must be requested explicitly.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: all
        description: 'Comma-separated fields to return (or ''all''). Sub-entities:
          phases, timerecords, messages, files, folders, invoices, workstages, bookmarks,
          projectnotes. Example: all,phases or phases,timerecords'
        in: query
        name: fields
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates an existing Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Project update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateProjectPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project
      tags:
      - projects
  /projects/{projectid}/access/{contactid}:
    get:
      consumes:
      - application/json
      description: Check whether a contact can view a Project. Staff can check access
        for any contact; non-staff contacts are always checked against themselves.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Contact ID or 'me'
        in: path
        name: contactid
        required: true
        type: string
      - default: "false"
        description: Return project title and number when access is granted
        enum:
        - "true"
        - "false"
        in: query
        name: details
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectAccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Check Project Access
      tags:
      - projects
  /projects/{projectid}/adjustdates:
    put:
      consumes:
      - application/json
      description: Shifts all dates on a Project forward or backward by a specified
        number of days.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.AdjustProjectDatesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Adjust Project Dates
      tags:
      - projects
  /projects/{projectid}/bookmarks:
    get:
      consumes:
      - application/json
      description: Returns a list of Bookmarks for a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Division ID (Advanced plan only)
        example: 1
        in: query
        name: divisionid
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectBookmarkListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Bookmarks
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Adds a Bookmark to a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CreateProjectBookmarkPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Bookmark
      tags:
      - projects
  /projects/{projectid}/bookmarks/{bookmarkid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Project Bookmark.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Bookmark ID
        in: path
        name: bookmarkid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Bookmark
      tags:
      - projects
    get:
      consumes:
      - application/json
      description: Returns details of a single Bookmark for a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Bookmark ID
        in: path
        name: bookmarkid
        required: true
        type: integer
      - description: Division ID (Advanced plan only)
        example: 1
        in: query
        name: divisionid
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectBookmarkGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Bookmark
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates a Project Bookmark.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Bookmark ID
        in: path
        name: bookmarkid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.UpdateProjectBookmarkPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Bookmark
      tags:
      - projects
  /projects/{projectid}/clone:
    post:
      consumes:
      - application/json
      description: Clones an existing project, optionally including its items and
        tags.
      parameters:
      - description: Project ID to clone
        in: path
        name: projectid
        required: true
        type: integer
      - description: Clone options (title is required)
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CloneProjectNexusRequest'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/handlers.CloneProjectNexusResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Clone Project
      tags:
      - projects
  /projects/{projectid}/complete:
    put:
      consumes:
      - application/json
      description: Marks a Project as complete.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Complete Project
      tags:
      - projects
  /projects/{projectid}/contacts:
    delete:
      consumes:
      - application/json
      description: Removes one or more Contacts from a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.UpdateProjectContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Project Contacts
      tags:
      - contacts
    get:
      consumes:
      - application/json
      description: Returns the Contacts assigned to a Project (staff, clients, contractors,
        and the project manager).
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: id,name,company,type
        description: 'Comma-separated list of fields to return. Available fields:
          address, company, image, lastmodified, name, roles, type'
        in: query
        name: fields
        type: string
      - description: Search by name. Use ! prefix for negation
        in: query
        name: searchname
        type: string
      - description: Search by email. Use ! prefix for negation
        in: query
        name: searchemail
        type: string
      - description: Filter by contact type
        enum:
        - client
        - contractor
        - staff
        - other
        in: query
        name: type
        type: string
      - description: Tag ID or comma-separated list of Tag IDs
        example: 1,2,3
        in: query
        name: tagid
        type: string
      - description: Role ID or comma-separated list of Role IDs
        example: 1,2,3
        in: query
        name: roleid
        type: string
      - description: Group ID or comma-separated list of Group IDs
        example: 1,2,3
        in: query
        name: groupid
        type: string
      - description: Filter by pending status
        enum:
        - "true"
        - "false"
        in: query
        name: pending
        type: string
      - description: Filter by login access
        enum:
        - "true"
        - "false"
        in: query
        name: allowlogin
        type: string
      - description: Division ID (Advanced plan only)
        example: 1
        in: query
        name: divisionid
        type: integer
      - description: Contacts modified on or after this date (UTC, ISO8601 or relative)
        example: 12h
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Contacts modified on or before this date (UTC, ISO8601 or relative)
        example: "2024-01-18"
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Contacts with ID >= this value
        in: query
        name: idfrom
        type: integer
      - description: Contacts with ID <= this value
        in: query
        name: idto
        type: integer
      - description: Comma-separated list of Contact IDs
        example: 1,2,3
        in: query
        name: id
        type: string
      - default: firstname
        description: Sort field
        enum:
        - id
        - firstname
        - lastname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Contacts
      tags:
      - contacts
    put:
      consumes:
      - application/json
      description: Updates the Contacts assigned to a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.UpdateProjectContactsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Contacts
      tags:
      - contacts
  /projects/{projectid}/customfields/{customfieldid}:
    put:
      consumes:
      - application/json
      description: Sets the value of a single custom field on a project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Custom Field ID
        in: path
        name: customfieldid
        required: true
        type: integer
      - description: Custom field value
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateProjectCustomFieldPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Custom Field Value
      tags:
      - projects
  /projects/{projectid}/files:
    get:
      consumes:
      - application/json
      description: Returns a list of Files for a Project based on the specified filters.
        The fields parameter allows you to choose which data fields to return for
        each File.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: name,item,date,size,link
        description: 'Comma-separated list of fields to return. Available: date, description,
          folder, link, name, owner, size, item'
        in: query
        name: fields
        type: string
      - description: Search by file name. Use ! prefix for negation
        example: report
        in: query
        name: search
        type: string
      - default: all
        description: Filter by item activeworkstate
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Item ID or comma-separated list of Item IDs
        example: 1,2
        in: query
        name: itemid
        type: string
      - description: Folder ID or comma-separated list of Folder IDs
        example: 1,2
        in: query
        name: folderid
        type: string
      - description: 'Files modified on or after this date (ISO8601 or relative: 12h,
          5d)'
        example: "2024-01-18"
        in: query
        name: datefrom
        type: string
      - description: Files modified on or before this date (ISO8601 or relative)
        example: "2024-01-18"
        in: query
        name: dateto
        type: string
      - description: Files with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Files with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of File IDs (comma-separated)
        example: 1,2,3
        in: query
        name: id
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - size
        - date
        - itemid
        - folderid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.FileListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Files
      tags:
      - projects
    post:
      consumes:
      - multipart/form-data
      description: 'Upload a file to a Project''s root folder. Send a multipart/form-data
        request with the file in the "file" field. To upload to a custom folder use
        POST /files/folders/{folderid}/files; to upload to a task folder use POST
        /projects/items/{itemid}/files. Blocked extensions: exe, msi, ini, bin, bat,
        cfm, cfc, asp, aspx, php, config, vb, java, pl.'
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: File to upload
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/handlers.FileUploadResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Upload Project File
      tags:
      - projects
  /projects/{projectid}/folders:
    get:
      consumes:
      - application/json
      description: Returns a list of custom Folders for a Project based on the specified
        filters.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: name
        description: 'Comma-separated fields to return. Available: name, description,
          type, size, date, owner, contacts, item, public'
        in: query
        name: fields
        type: string
      - description: Search by folder name. Use ! prefix for negation
        example: reports
        in: query
        name: search
        type: string
      - description: Folders with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Folders with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Folder IDs (comma-separated)
        example: 1,2,3
        in: query
        name: id
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.FolderListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Folders
      tags:
      - projects
  /projects/{projectid}/invoices:
    get:
      consumes:
      - application/json
      description: Returns a list of Invoices for a Project based on the specified
        filters.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: number,title,company,status,totals,projectid,invoiceddate,duedate
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by number or title. Use ! prefix for negation.
        in: query
        name: search
        type: string
      - description: Search by invoice number. Supports ! for negation.
        in: query
        name: searchnumber
        type: string
      - description: Search by invoice title. Supports ! for negation.
        in: query
        name: searchtitle
        type: string
      - description: Invoice status
        enum:
        - draft
        - submitted
        - authorised
        - paid
        - voided
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Filter by taxable status
        enum:
        - "true"
        - "false"
        - all
        in: query
        name: taxable
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Project manager Contact IDs (comma-separated)
        in: query
        name: managerid
        type: string
      - description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project category IDs (comma-separated)
        in: query
        name: projectcategoryid
        type: string
      - description: Company IDs (comma-separated)
        in: query
        name: companyid
        type: string
      - description: 'Invoiced date from (ISO8601 or relative: 12h, 5d, 2w, 1m)'
        in: query
        name: invoiceddatefrom
        type: string
      - description: Invoiced date to (ISO8601 or relative)
        in: query
        name: invoiceddateto
        type: string
      - description: Due date from (ISO8601 or relative)
        in: query
        name: duedatefrom
        type: string
      - description: Due date to (ISO8601 or relative)
        in: query
        name: duedateto
        type: string
      - description: Paid date from (ISO8601 or relative)
        in: query
        name: paiddatefrom
        type: string
      - description: Paid date to (ISO8601 or relative)
        in: query
        name: paiddateto
        type: string
      - description: Grand total minimum
        in: query
        name: grandtotalfrom
        type: string
      - description: Grand total maximum
        in: query
        name: grandtotalto
        type: string
      - description: Group results by. Returns subtotals per group.
        enum:
        - company
        - project
        - status
        - day
        - week
        - month
        - year
        in: query
        name: subtotals
        type: string
      - description: Date field for subtotals grouping
        enum:
        - invoiced
        - due
        - paid
        in: query
        name: subtotalsdateoption
        type: string
      - description: Invoices modified on or after this date (UTC, ISO8601 or relative)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Invoices modified on or before this date (UTC, ISO8601 or relative)
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Invoices with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Invoices with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Invoice IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - invoiceddate
        - duedate
        - companyname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Invoices
      tags:
      - projects
  /projects/{projectid}/items:
    get:
      consumes:
      - application/json
      description: Returns items for a project. Supports the same field selection,
        filtering, sorting, and pagination as GET /projects/items.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: name,status,priority
        description: Fields to return (see GET /projects/items for full list)
        in: query
        name: fields
        type: string
      - description: 'Deprecated: use name, code, or q+qfields instead. Search by
          name or code. Use ! for negation.'
        in: query
        name: search
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation.'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by description. Use
          ! for negation.'
        in: query
        name: searchdescription
        type: string
      - description: 'Deprecated: use code or q+qfields instead. Search by code. Use
          ! for negation.'
        in: query
        name: searchcode
        type: string
      - description: Exact name match
        in: query
        name: name
        type: string
      - description: Exact code match
        in: query
        name: code
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - code
        - description
        in: query
        name: qfields
        type: string
      - default: active
        description: Status filter
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Alias for status parameter.
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Priority filter (comma-separated)
        in: query
        name: priority
        type: string
      - description: Contact IDs or 'me' or 'unassigned'
        in: query
        name: contacts
        type: string
      - default: any
        description: Contacts filter mode
        enum:
        - any
        - all
        in: query
        name: contactsmode
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Work Stage ID
        in: query
        name: workstageid
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - code
        - priority
        - startdate
        - duedate
        - completedate
        - status
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Items
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Add an Item to a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CreateProjectItemPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Item
      tags:
      - projects
  /projects/{projectid}/items/{itemid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes a project item.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Item
      tags:
      - projects
    get:
      consumes:
      - application/json
      description: Returns full details of a single project item by ID.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectItemGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Item
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates an existing project item.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Item update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateProjectItemPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Item
      tags:
      - projects
  /projects/{projectid}/items/{itemid}/workstages:
    get:
      consumes:
      - application/json
      description: Returns the workstage history for a project item. Access is contact-filtered
        based on the authenticated user's project membership.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - default: setdatetime
        description: Sort field
        enum:
        - setdatetime
        - id
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ItemWorkStageHistoryListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Item Workstage History
      tags:
      - projects
  /projects/{projectid}/messages:
    get:
      consumes:
      - application/json
      description: Returns a list of Messages for a Project based on the specified
        filters.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: subject,content,originalmessageid,project,item,date,author,contacts,public,files
        description: 'Comma-separated list of fields to return. Available fields:
          subject, content, originalmessageid, project, item, date, author, contacts,
          public, files, replycount, all'
        in: query
        name: fields
        type: string
      - description: Search by subject. Use ! prefix for negation.
        in: query
        name: search
        type: string
      - description: Filter by contact. Comma-separated Contact IDs, 'me', or 'all'
        example: 1,2
        in: query
        name: contacts
        type: string
      - default: all
        description: Filter by item activeworkstate
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Item ID or list of Item IDs (comma-separated)
        example: 1,2
        in: query
        name: itemid
        type: string
      - description: Original Message ID - returns messages in the discussion started
          by this message
        example: "1"
        in: query
        name: originalmessageid
        type: string
      - description: 'Messages added on or after this date (ISO8601 or relative: 12h,
          5d, 2w, 1m)'
        example: "2024-01-18"
        in: query
        name: datefrom
        type: string
      - description: Messages added on or before this date (ISO8601 or relative)
        example: "2024-01-18"
        in: query
        name: dateto
        type: string
      - description: Messages with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Messages with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Message IDs (comma-separated)
        in: query
        name: id
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - date
        - originalmessageid
        - itemid
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.MessageListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Messages
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Creates a Message for a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CreateProjectMessagePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Message
      tags:
      - projects
  /projects/{projectid}/order:
    put:
      consumes:
      - application/json
      description: Moves a project before or after another project using sortorder.
        Provide exactly one of placeafterid or placebeforeid.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Order placement
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateProjectOrderRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Reorder Project
      tags:
      - projects
  /projects/{projectid}/phases:
    get:
      consumes:
      - application/json
      description: Returns phases (item collections) for a project with aggregated
        financial and progress metrics. Access is contact-filtered based on the authenticated
        user's project membership.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: id,name,projectid,parentid,timeallocated,timespent,estBillAmount,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by phase name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Filter to phases with a specific parent phase ID (0 = top-level
          only)
        in: query
        name: parentid
        type: integer
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        - startdate
        - duedate
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      - description: Phases modified on or after this date (UTC). ISO8601 or relative
          (12h, 5d, 2w, 1m)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Phases modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectPhaseListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Phases
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Add a Phase (Item Collection) to a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CreateProjectPhasePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Phase
      tags:
      - projects
  /projects/{projectid}/phases/{phaseid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes a project phase and its associated items.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Phase
      tags:
      - projects
    get:
      consumes:
      - application/json
      description: Returns full details of a single project phase (item collection)
        by ID. Includes all financial, time, billing, and progress fields.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectPhaseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Phase
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates an existing project phase.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      - description: Phase update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateProjectPhasePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Phase
      tags:
      - projects
  /projects/{projectid}/projectnotes:
    get:
      consumes:
      - application/json
      description: Returns a list of Project Notes for a Project based on the specified
        filters.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: title,content
        description: 'Comma-separated fields to return. Available: title, content,
          project, company, lastmodified, all'
        in: query
        name: fields
        type: string
      - description: Search by title. Use ! prefix for negation.
        example: website
        in: query
        name: search
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - description: Notes with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Notes with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Note IDs (comma-separated)
        example: 1,2,3
        in: query
        name: id
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - title
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectNoteListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Project Notes
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Creates a Project Note for a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.ProjectNoteCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Project Note
      tags:
      - projects
  /projects/{projectid}/projectnotes/{noteid}:
    delete:
      consumes:
      - application/json
      description: Deletes a Project Note from a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Project Note
      tags:
      - projects
    get:
      consumes:
      - application/json
      description: Returns details of a single Project Note for a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectnoteGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Project Note
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates a Project Note for a Project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Note ID
        in: path
        name: noteid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.ProjectNoteUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Project Note
      tags:
      - projects
  /projects/{projectid}/quotes:
    get:
      consumes:
      - application/json
      description: Returns a list of Quotes for a Project based on the specified filters.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: number,title,company,status,totals,quoteddate
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by number or title. Use ! prefix for negation.
        in: query
        name: search
        type: string
      - description: Search by quote number. Supports ! for negation.
        in: query
        name: searchnumber
        type: string
      - description: Search by quote title. Supports ! for negation.
        in: query
        name: searchtitle
        type: string
      - description: Quote status
        enum:
        - pending
        - sent
        - accepted
        - addedtoproject
        - declined
        - expired
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Quote type
        enum:
        - estimate
        - quote
        - all
        in: query
        name: type
        type: string
      - description: Filter by taxable status
        enum:
        - "true"
        - "false"
        - all
        in: query
        name: taxable
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Project manager Contact IDs (comma-separated)
        in: query
        name: managerid
        type: string
      - description: Project category IDs (comma-separated)
        in: query
        name: projectcategoryid
        type: string
      - description: 'Quoted date from (ISO8601 or relative: 12h, 5d, 2w, 1m)'
        in: query
        name: quoteddatefrom
        type: string
      - description: Quoted date to (ISO8601 or relative)
        in: query
        name: quoteddateto
        type: string
      - description: Approved date from (ISO8601 or relative)
        in: query
        name: approveddatefrom
        type: string
      - description: Approved date to (ISO8601 or relative)
        in: query
        name: approveddateto
        type: string
      - description: Valid to date from (ISO8601 or relative)
        in: query
        name: validtodatefrom
        type: string
      - description: Valid to date to (ISO8601 or relative)
        in: query
        name: validtodateto
        type: string
      - description: Grand total minimum
        in: query
        name: grandtotalfrom
        type: string
      - description: Grand total maximum
        in: query
        name: grandtotalto
        type: string
      - description: Group results by. Returns subtotals per group.
        enum:
        - company
        - project
        - status
        - day
        - week
        - month
        - year
        in: query
        name: subtotals
        type: string
      - description: Date field for subtotals grouping
        enum:
        - quoted
        - approved
        in: query
        name: subtotalsdateoption
        type: string
      - description: Quotes modified on or after this date (UTC, ISO8601 or relative)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Quotes modified on or before this date (UTC, ISO8601 or relative)
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Quotes with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Quotes with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Quote IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - quoteddate
        - validtodate
        - companyname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Quotes
      tags:
      - projects
  /projects/{projectid}/reactivate:
    put:
      consumes:
      - application/json
      description: 'Reactivates a Project. Note: this does not reactivate Tasks within
        the Project.'
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Reactivate Project
      tags:
      - projects
  /projects/{projectid}/settings:
    get:
      consumes:
      - application/json
      description: Returns the settings for a single Project, including client access,
        task visibility, and notification preferences.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectSettingsGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Settings
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates the settings for a Project, including client access, task
        visibility, and notification preferences.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.UpdateProjectSettingsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Settings
      tags:
      - projects
  /projects/{projectid}/time:
    get:
      consumes:
      - application/json
      description: Returns a list of Time Records for a Project based on the specified
        filters. Unlike GET /time, no default date range is applied — all time for
        the project is returned unless trackedfrom/trackedto are specified.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: contact,item,dates,timetracked
        description: 'Comma-separated fields to return. Available: contact, item,
          project, company, dates, timetracked, notes, billable, lastmodified, all'
        in: query
        name: fields
        type: string
      - description: Contact filter. Comma-separated Contact IDs, 'me', or 'all'
        example: 1,2,3
        in: query
        name: contacts
        type: string
      - description: Item ID or list of Item IDs (comma-separated)
        example: 1,2
        in: query
        name: itemid
        type: string
      - description: Company ID or list of Company IDs (comma-separated)
        example: 1,2
        in: query
        name: companyid
        type: string
      - description: Project Category ID or list of Category IDs (comma-separated)
        example: 1,2
        in: query
        name: categoryid
        type: string
      - description: 'Time tracked on or after this date. Accepts yyyy-mm-dd or relative:
          -6d, -1w, -1m, -1y'
        example: -6d
        in: query
        name: trackedfrom
        type: string
      - description: 'Time tracked on or before this date. Accepts yyyy-mm-dd or relative:
          +0d, +1w'
        example: +0d
        in: query
        name: trackedto
        type: string
      - default: all
        description: Billable filter
        enum:
        - billable
        - nonbillable
        - all
        in: query
        name: billable
        type: string
      - default: all
        description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - default: all
        description: Filter by item activeworkstate
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Search by notes. Use ! prefix for negation.
        in: query
        name: searchnotes
        type: string
      - description: Search by item name. Use ! prefix for negation.
        in: query
        name: searchitem
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Records modified on or after this date (UTC, ISO8601 or relative)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Records modified on or before this date (UTC, ISO8601 or relative)
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Records with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Records with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Time Record IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - date
        - itemid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TimeListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Time Records
      tags:
      - projects
  /projects/{projectid}/timeallocation:
    get:
      consumes:
      - application/json
      description: Returns a list of Time Allocations for a Project based on the specified
        filters.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: contact,item,project,time
        description: 'Comma-separated fields to return. Available: contact, item,
          project, time, labour, all'
        in: query
        name: fields
        type: string
      - description: Contact ID or list of Contact IDs (comma-separated)
        example: 1,2
        in: query
        name: contactid
        type: string
      - description: Item ID or list of Item IDs (comma-separated)
        example: 1,2
        in: query
        name: itemid
        type: string
      - default: active
        description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - description: Allocations with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Allocations with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Time Allocation IDs (comma-separated)
        example: 1,2,3
        in: query
        name: id
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - contactid
        - itemid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TimeAllocationListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Time Allocations
      tags:
      - projects
  /projects/{projectid}/workstage:
    put:
      consumes:
      - application/json
      description: Sets the active work stage for a project.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - description: Work stage
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateProjectWorkStageRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Work Stage
      tags:
      - projects
  /projects/{projectid}/workstages:
    get:
      consumes:
      - application/json
      description: Returns the workstage history for a project. Access is contact-filtered
        based on the authenticated user's project membership.
      parameters:
      - description: Project ID
        in: path
        name: projectid
        required: true
        type: integer
      - default: setdatetime
        description: Sort field
        enum:
        - setdatetime
        - id
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectWorkStageHistoryListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Workstage History
      tags:
      - projects
  /projects/adjustdates:
    put:
      consumes:
      - application/json
      description: Shifts start and due dates on one or more projects by a number
        of days. Negative values shift backwards. Optionally shifts child item dates
        too.
      parameters:
      - description: Project IDs and day offset
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkAdjustProjectDatesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Adjust Project Dates
      tags:
      - projects
  /projects/bookmarks:
    get:
      consumes:
      - application/json
      description: Returns a list of Bookmarks across all Projects.
      parameters:
      - description: Division ID (Advanced plan only)
        example: 1
        in: query
        name: divisionid
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectBookmarkListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get All Project Bookmarks
      tags:
      - projects
  /projects/contacts:
    delete:
      consumes:
      - application/json
      description: Removes one or more Contacts from one or more Projects.
      parameters:
      - description: Project IDs and Contact IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RemoveContactsFromProjectsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Contacts from Projects
      tags:
      - projects
  /projects/external:
    post:
      consumes:
      - application/json
      description: Creates a new external project with a company as the client.
      parameters:
      - description: External project data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateExternalProjectPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create External Project
      tags:
      - projects
  /projects/internal:
    post:
      consumes:
      - application/json
      description: Creates a new internal project with a staff member as the client.
      parameters:
      - description: Internal project data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateInternalProjectPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Internal Project
      tags:
      - projects
  /projects/invoices:
    post:
      consumes:
      - application/json
      description: Creates an Invoice based on project items.
      parameters:
      - description: Request body
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateInvoiceFromProjectPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Invoice From Project
      tags:
      - projects
  /projects/items:
    get:
      consumes:
      - application/json
      description: Returns a list of all project Items across all projects, based
        on the filters specified. The fields parameter allows you to choose which
        data fields to return for each Item.
      parameters:
      - default: name,status,priority
        description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>name</b></li><li><b>code</b></li><li><b>number</b></li><li><b>description</b></li><li><b>status</b></li><li><b>priority</b></li><li><b>percentcomplete</b></li><li><b>position</b></li><li><b>project</b></li><li><b>company</b></li><li><b>dates</b></li><li><b>time</b></li><li><b>billable</b></li><li><b>workstageid</b></li><li><b>parentid</b></li><li><b>phasename</b></li><li><b>categoryid</b></li><li><b>itemcollectionid</b></li><li><b>itemtypeid</b></li><li><b>createdon</b></li><li><b>contacts</b></li><li><b>tags</b></li><li><b>lastmodified</b></li><li><b>hourlyrateserviceid</b></li><li><b>productid</b></li><li><b>timebillable</b></li><li><b>creatorid</b></li><li><b>uniquetoken</b></li><li><b>deleted</b></li><li><b>prerequisiteid</b></li><li><b>dependenttaskid</b></li><li><b>contactid</b></li><li><b>tagid</b></li><li><b>quoteitemid</b></li><li><b>invoiceitemid</b></li><li><b>trackingoptionid</b></li><li><b>scoring</b></li><li><b>discount</b></li><li><b>units</b></li><li><b>tax</b></li><li><b>estimated</b></li><li><b>actual</b></li><li><b>projected</b></li><li><b>profit</b></li><li><b>budget</b></li><li><b>billing</b></li><li><b>invoiced</b></li><li><b>all</b></li></ul>'
        in: query
        name: fields
        type: string
      - description: 'Deprecated: use name, code, or q+qfields instead. Search by
          name or code. Use ! for negation.'
        in: query
        name: search
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by name. Use ! for
          negation.'
        in: query
        name: searchname
        type: string
      - description: 'Deprecated: use q+qfields instead. Search by description. Use
          ! for negation.'
        in: query
        name: searchdescription
        type: string
      - description: 'Deprecated: use code or q+qfields instead. Search by code. Use
          ! for negation.'
        in: query
        name: searchcode
        type: string
      - description: Exact name match
        in: query
        name: name
        type: string
      - description: Exact code match
        in: query
        name: code
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - name
        - code
        - description
        in: query
        name: qfields
        type: string
      - default: active
        description: Status filter
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Alias for status parameter.
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: 'Priority filter (comma-separated: 1=Very High … 5=Very Low)'
        in: query
        name: priority
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: Company IDs (comma-separated)
        in: query
        name: companyid
        type: string
      - description: Contact IDs assigned to item, 'me', or 'unassigned' for items
          with no contacts
        in: query
        name: contacts
        type: string
      - default: any
        description: Mode for contacts filter
        enum:
        - any
        - all
        in: query
        name: contactsmode
        type: string
      - description: Tag IDs (comma-separated)
        in: query
        name: tagid
        type: string
      - description: Work Stage ID
        in: query
        name: workstageid
        type: string
      - description: Start date from (yyyy-mm-dd)
        in: query
        name: startdatefrom
        type: string
      - description: Start date to (yyyy-mm-dd)
        in: query
        name: startdateto
        type: string
      - description: Due date from (yyyy-mm-dd)
        in: query
        name: duedatefrom
        type: string
      - description: Due date to (yyyy-mm-dd)
        in: query
        name: duedateto
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: integer
      - description: Last modified UTC from (ISO8601 or relative)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Last modified UTC to (ISO8601 or relative)
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Items with ID >= this value
        in: query
        name: idfrom
        type: integer
      - description: Items with ID <= this value
        in: query
        name: idto
        type: integer
      - description: List of Item IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: name
        description: Sort field
        enum:
        - id
        - name
        - code
        - priority
        - startdate
        - duedate
        - completedate
        - status
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Items
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Create an Item (assigns to a project via projectid in the request
        body).
      parameters:
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CreateItemPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Item
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates one or more project items by ID. All fields except ids
        are optional — only provided fields are updated.
      parameters:
      - description: Item IDs and fields to update
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdateItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Project Items
      tags:
      - projects
  /projects/items/{itemid}:
    delete:
      consumes:
      - application/json
      description: Soft delete an Item.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Item
      tags:
      - projects
    get:
      consumes:
      - application/json
      description: Returns full details of a single project item by ID.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectItemGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Item
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Update an existing Item. Only provide the fields you want to update.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Item update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateItemPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Item
      tags:
      - projects
  /projects/items/{itemid}/files:
    post:
      consumes:
      - multipart/form-data
      description: 'Upload a file to a Project Item (task folder). Send a multipart/form-data
        request with the file in the "file" field. The file is placed in the item''s
        task folder. Blocked extensions: exe, msi, ini, bin, bat, cfm, cfc, asp, aspx,
        php, config, vb, java, pl.'
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: File to upload
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/handlers.FileUploadResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Upload Project Item File
      tags:
      - projects
  /projects/items/{itemid}/order:
    put:
      consumes:
      - application/json
      description: Moves a project item before or after another item using sortorder.
        Provide exactly one of placeafterid or placebeforeid.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Order placement
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateItemOrderRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Reorder Project Item
      tags:
      - projects
  /projects/items/{itemid}/workstage:
    put:
      consumes:
      - application/json
      description: Sets the active work stage for a project item.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Work stage
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateItemWorkStageRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Item Work Stage
      tags:
      - projects
  /projects/items/clone:
    post:
      consumes:
      - application/json
      description: Clones one or more project items (tasks) into a target phase (item
        collection).
      parameters:
      - description: Item IDs and destination collection ID
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CloneItemsRequest'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Clone Items
      tags:
      - projects
  /projects/items/complete:
    put:
      consumes:
      - application/json
      description: Marks one or more project items as complete.
      parameters:
      - description: Array of item IDs to complete
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CompleteItemsRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Complete Items
      tags:
      - projects
  /projects/items/contacts:
    delete:
      consumes:
      - application/json
      description: Removes one or more Contacts from one or more Items (Tasks).
      parameters:
      - description: Item IDs and Contact IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.ContactsToItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Contacts from Items
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Adds one or more Contacts to one or more Items (Tasks).
      parameters:
      - description: Item IDs and Contact IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.ContactsToItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Contacts to Items
      tags:
      - projects
  /projects/items/contacts/all:
    delete:
      consumes:
      - application/json
      description: Removes all Contacts from one or more Items (Tasks).
      parameters:
      - description: Item IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RemoveAllContactsFromItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove All Contacts from Items
      tags:
      - projects
  /projects/items/move:
    put:
      consumes:
      - application/json
      description: Moves one or more project items (tasks) to a different phase (item
        collection).
      parameters:
      - description: Item IDs and destination phase ID
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.MoveItemsRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Move Items to Phase
      tags:
      - projects
  /projects/items/prerequisites:
    delete:
      consumes:
      - application/json
      description: Removes one or more prerequisite Items from one or more Items (Tasks).
      parameters:
      - description: Item IDs and Prerequisite Item IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.PrerequisitesToItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Prerequisites from Items
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Adds one or more prerequisite Items to one or more Items (Tasks).
      parameters:
      - description: Item IDs and Prerequisite Item IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.PrerequisitesToItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Prerequisites to Items
      tags:
      - projects
  /projects/items/tags:
    delete:
      consumes:
      - application/json
      description: Removes one or more Tags from one or more Items (Tasks).
      parameters:
      - description: Item IDs and Tag IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.TagsToItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Tags from Items
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Adds one or more Tags to one or more Items (Tasks).
      parameters:
      - description: Item IDs and Tag IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.TagsToItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Tags to Items
      tags:
      - projects
  /projects/items/tags/all:
    delete:
      consumes:
      - application/json
      description: Removes all Tags from one or more Items (Tasks).
      parameters:
      - description: Item IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RemoveAllTagsFromItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove All Tags from Items
      tags:
      - projects
  /projects/items/tracking:
    delete:
      consumes:
      - application/json
      description: Removes accounting integration tracking options from one or more
        Items (Tasks).
      parameters:
      - description: Item IDs and Tracking Option IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.TrackingOptionsToItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Tracking Options from Items
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Adds accounting integration tracking options to one or more Items
        (Tasks).
      parameters:
      - description: Item IDs and Tracking Option IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.TrackingOptionsToItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Tracking Options to Items
      tags:
      - projects
  /projects/items/workstage:
    put:
      consumes:
      - application/json
      description: Sets the active work stage for multiple project items.
      parameters:
      - description: Item IDs and work stage
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdateItemWorkStageRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Project Item Work Stage
      tags:
      - projects
  /projects/overdue:
    get:
      consumes:
      - application/json
      description: Returns active projects that are past their due date. Supports
        the same field selection, filtering, sorting, and pagination as GET /projects.
      parameters:
      - default: title,number,company,startdate,duedate
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by number or title. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Search by project number. Supports ! for negation.
        in: query
        name: searchnumber
        type: string
      - description: Company ID or list of Company IDs. Prefix with ! to negate.
        example: 1,2,3
        in: query
        name: companyid
        type: string
      - description: Manager Contact IDs, 'me', or 'all'. Prefix with ! to negate.
        example: 1,2
        in: query
        name: managerid
        type: string
      - description: Contact IDs, 'me', or 'all'. Prefix with ! to negate.
        example: 1,2
        in: query
        name: contacts
        type: string
      - default: any
        description: Mode for contacts filter
        enum:
        - any
        - all
        in: query
        name: contactsmode
        type: string
      - description: Team IDs (Advanced plan only). Prefix with ! to negate.
        example: 1,2
        in: query
        name: teamid
        type: string
      - description: Group IDs (Advanced plan only). Prefix with ! to negate.
        example: 1,2
        in: query
        name: groupid
        type: string
      - description: Category IDs. Prefix with ! to negate.
        example: 1,2,3
        in: query
        name: categoryid
        type: string
      - description: Tag IDs. Prefix with ! to negate.
        example: 1,2,3
        in: query
        name: tagid
        type: string
      - description: Priority or list of Priorities (1-5). Prefix with ! to negate.
        example: 1,2
        in: query
        name: priority
        type: string
      - description: Workstage IDs. Prefix with ! to negate.
        example: 1,2
        in: query
        name: workstageid
        type: string
      - description: 'Projects starting on or after this date (yyyy-mm-dd or relative:
          -3w)'
        example: -3w
        in: query
        name: startdatefrom
        type: string
      - description: Projects starting on or before this date (yyyy-mm-dd or relative)
        example: +0d
        in: query
        name: startdateto
        type: string
      - description: Projects due on or after this date (yyyy-mm-dd or relative)
        example: -6d
        in: query
        name: duedatefrom
        type: string
      - description: Projects completed on or after this date (yyyy-mm-dd or relative)
        in: query
        name: completedatefrom
        type: string
      - description: Projects completed on or before this date (yyyy-mm-dd or relative)
        in: query
        name: completedateto
        type: string
      - description: Projects modified on or after this date in UTC (ISO8601 or relative)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Projects modified on or before this date in UTC (ISO8601 or relative)
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Projects with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Projects with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Project IDs (comma-separated)
        example: 1,2,3
        in: query
        name: id
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - default: duedate
        description: Sort field
        enum:
        - id
        - number
        - title
        - startdate
        - duedate
        - completedate
        - companyname
        - categoryname
        - priority
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Overdue Projects
      tags:
      - projects
  /projects/phases:
    get:
      consumes:
      - application/json
      description: Returns phases (item collections) across all projects with aggregated
        financial and progress metrics. Optionally filter by one or more project IDs.
        Access is contact-filtered based on the authenticated user's project membership.
      parameters:
      - default: id,name,projectid,parentid,timeallocated,timespent,estBillAmount,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by phase name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Project ID or comma-separated list of Project IDs to filter by
        example: 1,2
        in: query
        name: projectid
        type: string
      - description: Filter to phases with a specific parent phase ID (0 = top-level
          only)
        in: query
        name: parentid
        type: integer
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        - startdate
        - duedate
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      - description: Phases modified on or after this date (UTC). ISO8601 or relative
          (12h, 5d, 2w, 1m)
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Phases modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectPhaseListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Phases
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Adds a Phase (Item Collection).
      parameters:
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.PhaseCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Phase
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates one or more project phases by ID. All fields except ids
        are optional.
      parameters:
      - description: Phase IDs and fields to update
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdatePhasesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Project Phases
      tags:
      - projects
  /projects/phases/{phaseid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Phase and its associated items.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Phase
      tags:
      - projects
    get:
      consumes:
      - application/json
      description: Returns full details of a single phase (item collection) by ID.
        Equivalent to GET /projects/{projectid}/phases/{phaseid} but looks up the
        phase by ID alone.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectPhaseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Phase
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates an existing Phase.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      - description: Phase update data
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.PhaseUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Phase
      tags:
      - projects
  /projects/phases/adjustdates:
    put:
      consumes:
      - application/json
      description: Shifts item dates within one or more project phases by a number
        of days. Negative values shift backwards.
      parameters:
      - description: Phase IDs and day offset
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkAdjustPhaseDatesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Adjust Project Phase Dates
      tags:
      - projects
  /projects/quotes:
    post:
      consumes:
      - application/json
      description: Creates a Quote based on project items.
      parameters:
      - description: Request body
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateQuoteFromProjectPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Quote From Project
      tags:
      - projects
  /projects/tags:
    delete:
      consumes:
      - application/json
      description: Removes one or more Tags from one or more Projects.
      parameters:
      - description: Project IDs and Tag IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RemoveTagsFromProjectsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Tags from Projects
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Adds one or more Tags to one or more Projects.
      parameters:
      - description: Project IDs and Tag IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.TagsToProjectsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Tags to Projects
      tags:
      - projects
  /projects/tags/all:
    delete:
      consumes:
      - application/json
      description: Removes all Tags from one or more Projects.
      parameters:
      - description: Project IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.RemoveAllTagsFromProjectsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove All Tags from Projects
      tags:
      - projects
  /quotes:
    delete:
      consumes:
      - application/json
      description: Soft deletes one or more quotes by ID.
      parameters:
      - description: Quote IDs to delete
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkDeleteQuotesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Delete Quotes
      tags:
      - quotes
    get:
      consumes:
      - application/json
      description: Returns a list of Quotes based on the filters specified. Optionally
        returns subtotals grouped by company, project, status, or time period.
      parameters:
      - default: number,title,company,status,totals,quoteddate
        description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>number</b> - Quote number</li><li><b>title</b> - Quote title</li><li><b>status</b>
          - Work state</li><li><b>activeworkstageid</b> - Active work stage ID</li><li><b>type</b>
          - Quote type (estimate or quote)</li><li><b>description</b> - Quote description
          (HTML stripped)</li><li><b>company</b> - Company ID and name</li><li><b>clientcontactname</b>
          - Client contact name</li><li><b>project</b> - Project ID</li><li><b>dates</b>
          - Quote date, valid date, approved date</li><li><b>quotedate</b> - Quote
          date only</li><li><b>validdate</b> - Valid date only</li><li><b>approveddate</b>
          - Approved date only</li><li><b>emaileddate</b> - Date quote was emailed</li><li><b>emailedtoclient</b>
          - Whether quote was emailed to client</li><li><b>emailedto</b> - Email address
          quote was sent to</li><li><b>showcostbreakdown</b> - Whether cost breakdown
          is shown</li><li><b>showitemdescription</b> - Whether item description is
          shown</li><li><b>showphases</b> - Whether phases are shown</li><li><b>quotedby</b>
          - Contact ID who created the quote</li><li><b>totals</b> - Subtotal, tax
          total, and grand total</li><li><b>budget</b> - Budget amount, tax, and type</li><li><b>billamount</b>
          - Bill amount, tax, and type</li><li><b>taxable</b> - Whether quote is taxable</li><li><b>taxrate</b>
          - Tax rate percentage</li><li><b>address</b> - Address fields</li><li><b>pagetitle</b>
          - Page title</li><li><b>customfield</b> - Custom field name and value</li><li><b>lastmodified</b>
          - Last modified date (UTC)</li><li><b>all</b> - All fields listed above</li></ul><br>Sub-entity
          fields (NOT included by <b>all</b> — must be named explicitly, e.g. <code>fields=all,phases</code>):<ul><li><b>phases</b>
          - Phase line items with nested items</li></ul>'
        in: query
        name: fields
        type: string
      - description: 'Deprecated: use number, title, or q+qfields instead. Search
          by number or title. Use ! for negation.'
        in: query
        name: search
        type: string
      - description: 'Deprecated: use number or q+qfields instead. Search by quote
          number. Supports ! for negation.'
        in: query
        name: searchnumber
        type: string
      - description: 'Deprecated: use title or q+qfields instead. Search by quote
          title. Supports ! for negation.'
        in: query
        name: searchtitle
        type: string
      - description: Exact number match
        in: query
        name: number
        type: string
      - description: Exact title match
        in: query
        name: title
        type: string
      - description: Fuzzy search term (use with qfields to restrict fields searched)
        in: query
        name: q
        type: string
      - description: Comma-separated fields to fuzzy search
        enum:
        - number
        - title
        in: query
        name: qfields
        type: string
      - description: 'Status (activeworkstate). Alias: activeworkstate.'
        enum:
        - pending
        - sent
        - accepted
        - addedtoproject
        - declined
        - expired
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Alias for status.
        enum:
        - pending
        - sent
        - accepted
        - addedtoproject
        - declined
        - expired
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Quote type
        enum:
        - estimate
        - quote
        - all
        in: query
        name: type
        type: string
      - description: Filter by taxable status
        enum:
        - "true"
        - "false"
        - all
        in: query
        name: taxable
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Project manager Contact IDs (comma-separated)
        in: query
        name: managerid
        type: string
      - description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Project category IDs (comma-separated)
        in: query
        name: projectcategoryid
        type: string
      - description: Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: Company IDs (comma-separated)
        in: query
        name: companyid
        type: string
      - description: Filter quotes by active work stage ID
        in: query
        name: workstageid
        type: string
      - description: 'Quoted date from (ISO8601 or relative: 12h, 5d, 2w, 1m)'
        in: query
        name: quoteddatefrom
        type: string
      - description: Quoted date to (ISO8601 or relative)
        in: query
        name: quoteddateto
        type: string
      - description: Approved date from (ISO8601 or relative)
        in: query
        name: approveddatefrom
        type: string
      - description: Approved date to (ISO8601 or relative)
        in: query
        name: approveddateto
        type: string
      - description: Valid to date from (ISO8601 or relative)
        in: query
        name: validtodatefrom
        type: string
      - description: Valid to date to (ISO8601 or relative)
        in: query
        name: validtodateto
        type: string
      - description: Grand total minimum
        in: query
        name: grandtotalfrom
        type: string
      - description: Grand total maximum
        in: query
        name: grandtotalto
        type: string
      - description: Group results by. Returns subtotals per group.
        enum:
        - company
        - project
        - status
        - day
        - week
        - month
        - year
        in: query
        name: subtotals
        type: string
      - description: Date field for subtotals grouping
        enum:
        - quoted
        - approved
        in: query
        name: subtotalsdateoption
        type: string
      - description: Quotes modified on or after this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Quotes modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Quotes with ID greater than or equal to this value
        in: query
        name: idfrom
        type: string
      - description: Quotes with ID less than or equal to this value
        in: query
        name: idto
        type: string
      - description: List of Quote IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: number
        description: Sort field
        enum:
        - id
        - number
        - title
        - quotedate
        - validdate
        - companyname
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quotes
      tags:
      - quotes
    post:
      consumes:
      - application/json
      description: Creates a new (blank) quote.
      parameters:
      - description: Quote data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateQuotePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Quote
      tags:
      - quotes
    put:
      consumes:
      - application/json
      description: Updates one or more quotes by ID. All fields except ids are optional
        — only provided fields are updated.
      parameters:
      - description: Quote IDs and fields to update
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdateQuotesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Quotes
      tags:
      - quotes
  /quotes/{quoteid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a quote by setting activeworkstate to 'deleted'.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Quote
      tags:
      - quotes
    get:
      consumes:
      - application/json
      description: 'View a single Quote. Returns detailed information including phases
        and line items. IMPORTANT: For Task/Staff Rate Lines, the ''rate'' value is
        cost/hour, the ''time'' value is the time in minutes.'
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote
      tags:
      - quotes
    put:
      consumes:
      - application/json
      description: Updates an existing quote. Only provide the fields you want to
        update.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Quote update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateQuotePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Quote
      tags:
      - quotes
  /quotes/{quoteid}/clone:
    post:
      consumes:
      - application/json
      description: Clones an existing quote.
      parameters:
      - description: Quote ID to clone
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Clone options
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CloneQuoteInvoiceRequest'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Clone Quote
      tags:
      - quotes
  /quotes/{quoteid}/items:
    get:
      consumes:
      - application/json
      description: Returns a list of line items for a quote. Supports field selection,
        filtering, sorting and pagination.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - default: id,name,itemcollectionid,parentid,itemtypeid,activeworkstate,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by item name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Filter to items within a specific phase (itemcollectionid)
        in: query
        name: phaseid
        type: integer
      - description: Filter by parent item ID (0 = top-level only)
        in: query
        name: parentid
        type: integer
      - description: Filter by item type ID
        in: query
        name: itemtypeid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Items
      tags:
      - quotes
    post:
      consumes:
      - application/json
      description: Creates one or more line items within a quote phase.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Item data (single object or array)
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateQuoteItemPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Quote Items
      tags:
      - quotes
  /quotes/{quoteid}/items/{itemid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes a quote line item.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Quote Item
      tags:
      - quotes
    get:
      consumes:
      - application/json
      description: Returns full details of a single quote line item by ID.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteItemGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Item
      tags:
      - quotes
    put:
      consumes:
      - application/json
      description: Updates an existing quote line item.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Item update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateQuoteItemPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Quote Item
      tags:
      - quotes
  /quotes/{quoteid}/items/{itemid}/workstages:
    get:
      consumes:
      - application/json
      description: Returns the workstage history for a quote line item.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - default: setdatetime
        description: Sort field
        enum:
        - setdatetime
        - id
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ItemWorkStageHistoryListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Item Workstage History
      tags:
      - quotes
  /quotes/{quoteid}/order:
    put:
      consumes:
      - application/json
      description: Moves a quote before or after another quote using sortorder. Provide
        exactly one of placeafterid or placebeforeid.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Order placement
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateQuoteOrderRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Reorder Quote
      tags:
      - quotes
  /quotes/{quoteid}/phases:
    get:
      consumes:
      - application/json
      description: Returns a list of phases (item collections) for a quote.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - default: id,name,quoteid,parentid,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by phase name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Filter to phases with a specific parent phase ID (0 = top-level
          only)
        in: query
        name: parentid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuotePhaseListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Phases
      tags:
      - quotes
    post:
      consumes:
      - application/json
      description: Creates one or more phases (item collections) within a quote.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Phase data (single object or array)
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateQuotePhasePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Quote Phases
      tags:
      - quotes
  /quotes/{quoteid}/phases/{phaseid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes a quote phase and its associated items.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Quote Phase
      tags:
      - quotes
    get:
      consumes:
      - application/json
      description: Returns full details of a single quote phase (item collection)
        by ID.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuotePhaseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Phase
      tags:
      - quotes
    put:
      consumes:
      - application/json
      description: Updates an existing quote phase.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      - description: Phase update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateQuotePhasePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Quote Phase
      tags:
      - quotes
  /quotes/{quoteid}/workstage:
    put:
      consumes:
      - application/json
      description: Sets the active work stage for a quote.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - description: Work stage
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateQuoteWorkStageRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Quote Work Stage
      tags:
      - quotes
  /quotes/{quoteid}/workstages:
    get:
      consumes:
      - application/json
      description: Returns the workstage history for a quote.
      parameters:
      - description: Quote ID
        in: path
        name: quoteid
        required: true
        type: integer
      - default: setdatetime
        description: Sort field
        enum:
        - setdatetime
        - id
        in: query
        name: sortby
        type: string
      - default: desc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteWorkStageHistoryListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Workstage History
      tags:
      - quotes
  /quotes/items:
    get:
      consumes:
      - application/json
      description: Returns a list of all quote line items across all quotes, based
        on the filters specified.
      parameters:
      - default: id,name,itemcollectionid,parentid,itemtypeid,activeworkstate,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by item name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Quote ID or list of Quote IDs (comma-separated)
        in: query
        name: quoteid
        type: string
      - description: Filter to items within a specific phase (itemcollectionid)
        in: query
        name: phaseid
        type: integer
      - description: Filter by parent item ID (0 = top-level only)
        in: query
        name: parentid
        type: integer
      - description: Filter by item type ID
        in: query
        name: itemtypeid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Items
      tags:
      - quotes
    post:
      consumes:
      - application/json
      description: Creates one or more quote line items. The quoteid must be provided
        in the request body.
      parameters:
      - description: Item data (single object or array)
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateQuoteItemPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Quote Items
      tags:
      - quotes
    put:
      consumes:
      - application/json
      description: Updates one or more quote items by ID. All fields except ids are
        optional — only provided fields are updated.
      parameters:
      - description: Item IDs and fields to update
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdateItemsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Quote Items
      tags:
      - quotes
  /quotes/items/{itemid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes a quote line item by ID, without requiring the quote
        ID.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Quote Item
      tags:
      - quotes
    get:
      consumes:
      - application/json
      description: Returns full details of a single quote line item by ID, without
        requiring the quote ID.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteItemGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Item
      tags:
      - quotes
    put:
      consumes:
      - application/json
      description: Updates an existing quote line item by ID, without requiring the
        quote ID.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Item update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateQuoteItemPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Quote Item
      tags:
      - quotes
  /quotes/items/{itemid}/order:
    put:
      consumes:
      - application/json
      description: Moves a quote item before or after another item using sortorder.
        Provide exactly one of placeafterid or placebeforeid.
      parameters:
      - description: Item ID
        in: path
        name: itemid
        required: true
        type: integer
      - description: Order placement
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateQuoteItemOrderRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Reorder Quote Item
      tags:
      - quotes
  /quotes/phases:
    get:
      consumes:
      - application/json
      description: Returns phases (item collections) across all quotes. Optionally
        filter by one or more quote IDs.
      parameters:
      - default: id,name,quoteid,parentid,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by phase name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Quote ID or comma-separated list of Quote IDs to filter by
        example: 1,2
        in: query
        name: quoteid
        type: string
      - description: Filter to phases with a specific parent phase ID (0 = top-level
          only)
        in: query
        name: parentid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuotePhaseListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Phases
      tags:
      - quotes
    post:
      consumes:
      - application/json
      description: Creates one or more quote phases (item collections). The quoteid
        must be included in the request body.
      parameters:
      - description: Phase data (single object or array)
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateQuotePhasePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Quote Phases
      tags:
      - quotes
    put:
      consumes:
      - application/json
      description: Updates one or more quote phases by ID. All fields except ids are
        optional.
      parameters:
      - description: Phase IDs and fields to update
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkUpdatePhasesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Update Quote Phases
      tags:
      - quotes
  /quotes/phases/{phaseid}:
    delete:
      consumes:
      - application/json
      description: Soft-deletes a quote phase by ID.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Quote Phase
      tags:
      - quotes
    get:
      consumes:
      - application/json
      description: Returns full details of a single quote phase by ID. Looks up the
        phase by ID alone.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuotePhaseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Phase
      tags:
      - quotes
    put:
      consumes:
      - application/json
      description: Updates an existing quote phase by ID.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      - description: Phase update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateQuotePhasePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Quote Phase
      tags:
      - quotes
  /quotes/phases/adjustdates:
    put:
      consumes:
      - application/json
      description: Shifts item dates within one or more quote phases by a number of
        days. Negative values shift backwards.
      parameters:
      - description: Phase IDs and day offset
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.BulkAdjustPhaseDatesPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Bulk Adjust Quote Phase Dates
      tags:
      - quotes
  /settings/account:
    get:
      consumes:
      - application/json
      description: Returns Account settings, including plan details, plugin status,
        currency, project variable, time and look &amp; feel.
      parameters:
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.settingsAccountResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Account Settings
      tags:
      - settings
  /settings/account/license:
    get:
      consumes:
      - application/json
      description: Returns details of the available, used and total licenses.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.LicenseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Account License Details
      tags:
      - settings
  /settings/account/looknfeel:
    get:
      consumes:
      - application/json
      description: Returns Look &amp; Feel Settings including logo and color scheme.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.LooknfeelListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Look & Feel Settings
      tags:
      - settings
  /settings/account/plan:
    get:
      consumes:
      - application/json
      description: Returns details of the Plan (Professional/Advanced) and plugin
        status (invoicesplugin/quotesplugin) for the account.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.settingsAccountPlanResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Account Plan
      tags:
      - settings
  /settings/contacts/divisions:
    get:
      consumes:
      - application/json
      description: Returns a list of Divisions. Advanced plan only.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.DivisionListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Divisions
      tags:
      - settings
  /settings/contacts/divisions/{divisionid}:
    get:
      consumes:
      - application/json
      description: Returns details of a single Division. Advanced plan only.
      parameters:
      - description: Division ID
        in: path
        name: divisionid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.DivisionGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Division
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates a division. Advanced plan only.
      parameters:
      - description: Division ID
        in: path
        name: divisionid
        required: true
        type: integer
      - description: Division update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateDivisionPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Division
      tags:
      - settings
  /settings/contacts/groups:
    get:
      consumes:
      - application/json
      description: Returns a list of Groups including Contacts in each Group.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactGroupListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Groups
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new contact group.
      parameters:
      - description: Group data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateGroupPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Group
      tags:
      - settings
  /settings/contacts/groups/{groupid}:
    delete:
      consumes:
      - application/json
      description: Deletes a group.
      parameters:
      - description: Group ID
        in: path
        name: groupid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Group
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Group including the Contacts in the
        Group.
      parameters:
      - description: Group ID
        in: path
        name: groupid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactGroupGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Group
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates a group.
      parameters:
      - description: Group ID
        in: path
        name: groupid
        required: true
        type: integer
      - description: Group update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateGroupPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Group
      tags:
      - settings
  /settings/contacts/permissions:
    get:
      consumes:
      - application/json
      description: Returns a list of available Permissions in ProWorkflow.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.PermissionSettingsListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Permissions
      tags:
      - settings
  /settings/contacts/roles:
    get:
      consumes:
      - application/json
      description: Returns a list of Roles including assigned Contacts.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.RoleListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Roles
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new role.
      parameters:
      - description: Role data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateRolePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Role
      tags:
      - settings
  /settings/contacts/roles/{roleid}:
    delete:
      consumes:
      - application/json
      description: Deletes a role.
      parameters:
      - description: Role ID
        in: path
        name: roleid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Role
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Role including assigned Contacts.
      parameters:
      - description: Role ID
        in: path
        name: roleid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.RoleGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Role
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates a role's name, color, display order, permissions, and/or
        assigned contacts.
      parameters:
      - description: Role ID
        in: path
        name: roleid
        required: true
        type: integer
      - description: Role update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateRolePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Role
      tags:
      - settings
  /settings/contacts/tags:
    get:
      consumes:
      - application/json
      description: Returns a list of Contact/Company Tags.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactTagListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contact/Company Tags
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new Contact/Company Tag.
      parameters:
      - description: Contact tag data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateContactTagPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Contact Tag
      tags:
      - settings
  /settings/contacts/tags/{tagid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Contact Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Contact Tag
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Contact Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ContactTagGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Contact Tag
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates a Contact Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      - description: Contact tag update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateContactTagPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Contact Tag
      tags:
      - settings
  /settings/contacts/teams:
    get:
      consumes:
      - application/json
      description: Returns a list of Teams including the Groups in each Team.
      parameters:
      - default: id,name,code,groupid
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by team name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TeamListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Teams
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new team.
      parameters:
      - description: Team data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateTeamPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Team
      tags:
      - settings
  /settings/contacts/teams/{teamid}:
    delete:
      consumes:
      - application/json
      description: Deletes a team.
      parameters:
      - description: Team ID
        in: path
        name: teamid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Team
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Team including the Groups in the Team.
      parameters:
      - description: Team ID
        in: path
        name: teamid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TeamGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Team
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates a team.
      parameters:
      - description: Team ID
        in: path
        name: teamid
        required: true
        type: integer
      - description: Team update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateTeamPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Team
      tags:
      - settings
  /settings/invoices/autonumbering:
    get:
      consumes:
      - application/json
      description: Returns the Invoices Autonumbering settings including mask, count,
        and placeholder.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.SettingsInvoicesAutonumberingListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoices Autonumbering Settings
      tags:
      - settings
  /settings/invoices/templates:
    get:
      consumes:
      - application/json
      description: Returns a simple list of Invoice Templates.
      parameters:
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceTemplateListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Templates
      tags:
      - invoices
  /settings/invoices/templates/{templateid}:
    get:
      consumes:
      - application/json
      description: Returns detailed information about a single Invoice Template, including
        phases and line items.
      parameters:
      - description: Template ID
        in: path
        name: templateid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.InvoiceGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Template
      tags:
      - settings
  /settings/items/categories:
    get:
      consumes:
      - application/json
      description: Returns a list of Item Categories.
      parameters:
      - default: id,name,color,sortorder,lastmodifiedutc
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by category name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ItemCategoryListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Item Categories
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new Item Category.
      parameters:
      - description: Item category data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateItemCategoryPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Item Category
      tags:
      - settings
  /settings/items/categories/{categoryid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes an Item Category.
      parameters:
      - description: Category ID
        in: path
        name: categoryid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Item Category
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Item Category.
      parameters:
      - description: Category ID
        in: path
        name: categoryid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ItemCategoryGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Item Category
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates an Item Category.
      parameters:
      - description: Category ID
        in: path
        name: categoryid
        required: true
        type: integer
      - description: Item category update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateItemCategoryPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Item Category
      tags:
      - settings
  /settings/items/tags:
    get:
      consumes:
      - application/json
      description: Returns a list of Item Tags.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ItemTagListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Item Tags
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new Item Tag.
      parameters:
      - description: Item tag data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateItemTagPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Item Tag
      tags:
      - settings
  /settings/items/tags/{tagid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes an Item Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Item Tag
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Item Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ItemTagGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Item Tag
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates an Item Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      - description: Item tag update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateItemTagPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Item Tag
      tags:
      - settings
  /settings/items/tags/items:
    delete:
      consumes:
      - application/json
      description: Removes one or more Items (Tasks) from one or more Task Tags.
      parameters:
      - description: Tag IDs and Item IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.ItemsToTagsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Remove Items from Tags
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Adds one or more Items (Tasks) to one or more Task Tags.
      parameters:
      - description: Tag IDs and Item IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.ItemsToTagsPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Items to Tags
      tags:
      - settings
  /settings/product/fixedprice:
    get:
      consumes:
      - application/json
      description: Returns a list of products from the Fixed Price Library. These
        are products charged at a set price per unit (ItemType hasLabour=0, hasQuantity=1).
        Price fields (inUnitPrice, outUnitPrice) are excluded for security.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.SettingsProductFixedpriceListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Fixed Price Library
      tags:
      - settings
  /settings/product/goodservice:
    get:
      consumes:
      - application/json
      description: Returns a list of products from the Goods and Services Library.
        These are products charged with both a set price and an hourly rate (ItemType
        hasLabour=1, hasQuantity=1). Price fields (inUnitPrice, outUnitPrice) are
        excluded for security.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.SettingsProductGoodserviceListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Goods and Services Library
      tags:
      - settings
  /settings/product/hourlyservice:
    get:
      consumes:
      - application/json
      description: Returns a list of products from the Hourly Services Library. These
        are products charged at an hourly rate (ItemType hasLabour=1, hasQuantity=0).
        Price fields (inUnitPrice, outUnitPrice) are excluded for security.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.SettingsProductHourlyserviceListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Hourly Services Library
      tags:
      - settings
  /settings/projects:
    get:
      consumes:
      - application/json
      description: Returns default Project settings. These can be changed from the
        main ProWorkflow application.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.SettingsProjectsListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Settings
      tags:
      - settings
  /settings/projects/autonumbering:
    get:
      consumes:
      - application/json
      description: Returns the Projects Autonumbering settings including mask, count,
        and placeholder.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.SettingsProjectsAutonumberingListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Projects Autonumbering Settings
      tags:
      - settings
  /settings/projects/categories:
    get:
      consumes:
      - application/json
      description: Returns a list of Project Categories.
      parameters:
      - default: id,name,color,sortorder,lastmodifiedutc,projectcount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by category name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectCategoryListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Categories
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new Project Category.
      parameters:
      - description: Project category data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateProjectCategoryPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Category
      tags:
      - settings
  /settings/projects/categories/{categoryid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Project Category.
      parameters:
      - description: Category ID
        in: path
        name: categoryid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Category
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Project Category.
      parameters:
      - description: Category ID
        in: path
        name: categoryid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectCategoryGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Category
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates a Project Category.
      parameters:
      - description: Category ID
        in: path
        name: categoryid
        required: true
        type: integer
      - description: Project category update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateProjectCategoryPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Category
      tags:
      - settings
  /settings/projects/customfieldoptions:
    post:
      consumes:
      - application/json
      description: Creates a new option for a Project Custom Field.
      parameters:
      - description: Custom field option data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateCustomFieldOptionPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Custom Field Option
      tags:
      - projects
  /settings/projects/customfieldoptions/{optionid}:
    delete:
      consumes:
      - application/json
      description: Deletes an option for a Project Custom Field.
      parameters:
      - description: Custom Field Option ID
        in: path
        name: optionid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Custom Field Option
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates an option for a Project Custom Field.
      parameters:
      - description: Custom Field Option ID
        in: path
        name: optionid
        required: true
        type: integer
      - description: Custom field option update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateCustomFieldOptionPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Custom Field Option
      tags:
      - projects
  /settings/projects/customfields:
    get:
      consumes:
      - application/json
      description: Returns a list of Custom Fields including the Options for each
        Field. Advanced plan only.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CustomFieldListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Custom Fields
      tags:
      - projects
    post:
      consumes:
      - application/json
      description: Creates a new Project Custom Field.
      parameters:
      - description: Custom field data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateCustomFieldPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Custom Field
      tags:
      - projects
  /settings/projects/customfields/{customfieldid}:
    delete:
      consumes:
      - application/json
      description: Deletes a Project Custom Field.
      parameters:
      - description: Custom Field ID
        in: path
        name: customfieldid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Custom Field
      tags:
      - projects
    put:
      consumes:
      - application/json
      description: Updates a Project Custom Field.
      parameters:
      - description: Custom Field ID
        in: path
        name: customfieldid
        required: true
        type: integer
      - description: Custom field update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateCustomFieldPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Custom Field
      tags:
      - projects
  /settings/projects/tags:
    get:
      consumes:
      - application/json
      description: Returns a list of Project Tags.
      parameters:
      - default: id,name,color,lastmodifiedutc
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by tag name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectTagListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Tags
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new Project Tag.
      parameters:
      - description: Project tag data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateProjectTagPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Project Tag
      tags:
      - settings
  /settings/projects/tags/{tagid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Project Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Project Tag
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Project Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectTagGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Tag
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates a Project Tag.
      parameters:
      - description: Tag ID
        in: path
        name: tagid
        required: true
        type: integer
      - description: Project tag update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateProjectTagPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Project Tag
      tags:
      - settings
  /settings/projects/templates:
    get:
      consumes:
      - application/json
      description: Returns a list of Project Templates. Advanced plan only.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectTemplateListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Templates
      tags:
      - projects
  /settings/projects/templates/{projecttemplateid}:
    get:
      consumes:
      - application/json
      description: Returns detailed information about a single Project Template, including
        tasks.
      parameters:
      - description: Project Template ID
        in: path
        name: projecttemplateid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ProjectGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Template
      tags:
      - settings
  /settings/projects/templates/{projecttemplateid}/items:
    get:
      consumes:
      - application/json
      description: Returns line items for a specific project template.
      parameters:
      - description: Project Template ID
        in: path
        name: projecttemplateid
        required: true
        type: integer
      - default: id,name,itemcollectionid,parentid,itemtypeid,activeworkstate
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by item name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Filter to items within a specific phase (itemcollectionid)
        in: query
        name: phaseid
        type: integer
      - description: Filter by parent item ID (0 = top-level only)
        in: query
        name: parentid
        type: integer
      - description: Filter by item type ID
        in: query
        name: itemtypeid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TemplateItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Template Items by Template
      tags:
      - settings
  /settings/projects/templates/{projecttemplateid}/phases:
    get:
      consumes:
      - application/json
      description: Returns phases (item collections) for a specific project template.
      parameters:
      - description: Project Template ID
        in: path
        name: projecttemplateid
        required: true
        type: integer
      - default: id,name,itemcollectiontemplateid,parentid,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by phase name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Filter to phases with a specific parent phase ID (0 = top-level
          only)
        in: query
        name: parentid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TemplatePhaseListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Template Phases by Template
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Adds a Phase (Item Collection) to a specific project template.
      parameters:
      - description: Project Template ID
        in: path
        name: projecttemplateid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.CreateTemplatePhaseForTemplatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Template Phase
      tags:
      - settings
  /settings/projects/templates/{projecttemplateid}/phases/{phaseid}:
    get:
      consumes:
      - application/json
      description: Returns full details of a single template phase (item collection)
        by ID within a specific template.
      parameters:
      - description: Project Template ID
        in: path
        name: projecttemplateid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TemplatePhaseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Template Phase
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates an existing template phase within a specific project template.
      parameters:
      - description: Project Template ID
        in: path
        name: projecttemplateid
        required: true
        type: integer
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      - description: Phase update data
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.TemplatePhaseUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Template Phase
      tags:
      - settings
  /settings/quotes:
    get:
      consumes:
      - application/json
      description: Returns default Quote settings. These can be changed from the main
        ProWorkflow application.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.SettingsQuotesListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Settings
      tags:
      - settings
  /settings/quotes/autonumbering:
    get:
      consumes:
      - application/json
      description: Returns the Quotes Autonumbering settings including mask, count,
        and placeholder.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.SettingsQuotesAutonumberingListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quotes Autonumbering Settings
      tags:
      - settings
  /settings/quotes/templates:
    get:
      consumes:
      - application/json
      description: Returns a list of Quote Templates.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteTemplateListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Templates
      tags:
      - settings
  /settings/quotes/templates/{templateid}:
    get:
      consumes:
      - application/json
      description: Returns detailed information about a single Quote Template, including
        phases and line items.
      parameters:
      - description: Template ID
        in: path
        name: templateid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.QuoteGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Template
      tags:
      - settings
  /settings/servicerates:
    get:
      consumes:
      - application/json
      description: Returns a list of Hourly Rate Services (service rates). Price fields
        (inLabourPrice, outLabourPrice, outLabourPriceMultiplier) are excluded for
        security.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ServiceRateListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Hourly Rate Services
      tags:
      - settings
  /settings/staffrates:
    get:
      consumes:
      - application/json
      description: Returns a list of staff members with their default hourly rate
        service and sell rate. Pay rate and cost rate fields are excluded for security.
        In v3 this was available at /settings/quotes/staffrates and /settings/invoices/staffrates
        — those are now consolidated here.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.StaffRateListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Staff Rates
      tags:
      - settings
  /settings/webhooks:
    get:
      consumes:
      - application/json
      description: Returns a list of active Webhook subscriptions for the account.
      parameters:
      - default: all
        description: Event type filter
        enum:
        - all
        - newcontact
        - newpendingcontact
        - editcontact
        - editcontactlocation
        - deletecontact
        - newcompany
        - newpendingcompany
        - editcompany
        - deletecompany
        - newfile
        - deletefile
        - newinvoice
        - editinvoice
        - deleteinvoice
        - newmessage
        - editmessage
        - deletemessage
        - newproject
        - editproject
        - editstageproject
        - deleteproject
        - completeproject
        - restoreProject
        - newprojectrequest
        - editprojectrequest
        - deleteprojectrequest
        - approveprojectrequest
        - declineprojectrequest
        - newquote
        - editquote
        - deletequote
        - newsharednote
        - editsharednote
        - deletesharednote
        - newtask
        - edittask
        - deletetask
        - completetask
        - reactivatetask
        - newtime
        - edittime
        - deletetime
        - starttimer
        - stoptimer
        - unknown
        in: query
        name: event
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ResthookListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Webhooks
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Creates a new Webhook subscription.
      parameters:
      - description: Webhook subscription data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.CreateResthookPayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Webhook
      tags:
      - settings
  /settings/webhooks/{webhookid}:
    delete:
      consumes:
      - application/json
      description: Soft deletes a Webhook subscription.
      parameters:
      - description: Webhook ID
        in: path
        name: webhookid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Webhook
      tags:
      - settings
    get:
      consumes:
      - application/json
      description: Returns details of a single Webhook subscription.
      parameters:
      - description: Webhook ID
        in: path
        name: webhookid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Webhook
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates a Webhook subscription.
      parameters:
      - description: Webhook ID
        in: path
        name: webhookid
        required: true
        type: integer
      - description: Webhook update data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateResthookPayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Webhook
      tags:
      - settings
  /settings/webhooks/requests:
    get:
      consumes:
      - application/json
      description: Returns a list of Webhook delivery requests for debugging. Requests
        older than 7 days are automatically deleted.
      parameters:
      - default: all
        description: Event type filter
        enum:
        - all
        - company
        - contact
        - file
        - invoice
        - message
        - project
        - projectrequest
        - quote
        - sharednote
        - task
        - time
        - timer
        in: query
        name: event
        type: string
      - description: Web Hook ID or comma-separated list of IDs
        in: query
        name: resthookid
        type: string
      - default: pending
        description: Request status filter
        enum:
        - pending
        - complete
        - all
        in: query
        name: status
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ResthookRequestListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Webhook Requests
      tags:
      - settings
  /settings/workstages:
    get:
      consumes:
      - application/json
      description: Returns a list of Work Stages. Use the type parameter to filter
        by stage type.
      parameters:
      - description: Filter by work stage type
        enum:
        - item
        - project
        - quote
        - invoice
        in: query
        name: type
        type: string
      - description: Filter by work state (exact match)
        example: active
        in: query
        name: workstate
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.WorkStageListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Work Stages
      tags:
      - settings
  /settings/workstages/invoice:
    get:
      consumes:
      - application/json
      description: Returns a list of Work Stages for type 'invoice'
      parameters:
      - description: Filter by work state (exact match)
        example: active
        in: query
        name: workstate
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.WorkStageListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Invoice Work Stages
      tags:
      - settings
  /settings/workstages/item:
    get:
      consumes:
      - application/json
      description: Returns a list of Work Stages for type 'item'
      parameters:
      - description: Filter by work state (exact match)
        example: active
        in: query
        name: workstate
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.WorkStageListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Item Work Stages
      tags:
      - settings
  /settings/workstages/project:
    get:
      consumes:
      - application/json
      description: Returns a list of Work Stages for type 'project'
      parameters:
      - description: Filter by work state (exact match)
        example: active
        in: query
        name: workstate
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.WorkStageListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Project Work Stages
      tags:
      - settings
  /settings/workstages/quote:
    get:
      consumes:
      - application/json
      description: Returns a list of Work Stages for type 'quote'
      parameters:
      - description: Filter by work state (exact match)
        example: active
        in: query
        name: workstate
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.WorkStageListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Quote Work Stages
      tags:
      - settings
  /templateitems:
    get:
      consumes:
      - application/json
      description: Returns a list of all template line items across all templates,
        based on the filters specified.
      parameters:
      - default: id,name,itemcollectionid,parentid,itemtypeid,activeworkstate
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by item name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Template ID or list of Template IDs (comma-separated)
        example: 1,2,3
        in: query
        name: templateid
        type: string
      - description: Filter to items within a specific phase (itemcollectionid)
        in: query
        name: phaseid
        type: integer
      - description: Filter by parent item ID (0 = top-level only)
        in: query
        name: parentid
        type: integer
      - description: Filter by item type ID
        in: query
        name: itemtypeid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TemplateItemListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Template Items
      tags:
      - settings
  /templateitems/{itemid}:
    get:
      consumes:
      - application/json
      description: Returns full details of a single template item by ID.
      parameters:
      - description: Template Item ID
        in: path
        name: itemid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TemplateItemGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Template Item
      tags:
      - settings
  /templatephases:
    get:
      consumes:
      - application/json
      description: Returns a list of all template phases (item collections) across
        all templates.
      parameters:
      - default: id,name,itemcollectiontemplateid,parentid,billAmount
        description: Comma-separated fields to return, or 'all'
        in: query
        name: fields
        type: string
      - description: Search by phase name. Prefix with ! to negate.
        in: query
        name: search
        type: string
      - description: Template ID or comma-separated list of Template IDs
        example: 1,2
        in: query
        name: templateid
        type: string
      - description: Filter to phases with a specific parent phase ID (0 = top-level
          only)
        in: query
        name: parentid
        type: integer
      - default: sortorder
        description: Sort field
        enum:
        - id
        - name
        - sortorder
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort direction
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TemplatePhaseListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Template Phases
      tags:
      - settings
    post:
      consumes:
      - application/json
      description: Adds a Phase (Item Collection) to a template.
      parameters:
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.TemplatePhaseCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Template Phase
      tags:
      - settings
  /templatephases/{phaseid}:
    get:
      consumes:
      - application/json
      description: Returns full details of a single template phase (item collection)
        by ID.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TemplatePhaseGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Template Phase
      tags:
      - settings
    put:
      consumes:
      - application/json
      description: Updates an existing template phase.
      parameters:
      - description: Phase ID
        in: path
        name: phaseid
        required: true
        type: integer
      - description: Phase update data
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.TemplatePhaseUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Template Phase
      tags:
      - settings
  /time:
    get:
      consumes:
      - application/json
      description: Returns a list of Time Records based on the filters specified.
        By default returns time tracked in the last 6 days. The fields parameter controls
        which data is returned for each record.
      parameters:
      - default: contact,item,dates,timetracked
        description: 'Comma-separated list of fields to return. Available fields:
          <ul><li><b>contact</b> - Contact ID and name</li><li><b>item</b> (or <b>task</b>)
          - Item ID and name</li><li><b>itemid</b> (or <b>taskid</b>) - Item ID only</li><li><b>itemname</b>
          (or <b>taskname</b>) - Item name only</li><li><b>project</b> - Project ID,
          title, and number</li><li><b>company</b> - Company ID and name</li><li><b>dates</b>
          - Start date, start time, end time</li><li><b>timetracked</b> - Time spent
          (in minutes)</li><li><b>notes</b> - Time record notes</li><li><b>billable</b>
          - Billable flag (from item)</li><li><b>accountedfor</b> - Accounted for
          flag</li><li><b>timeallocationid</b> - Time allocation ID</li><li><b>itemcollectionid</b>
          - Item collection (phase) ID</li><li><b>lastmodified</b> - Last modified
          date (UTC)</li><li><b>all</b> - All fields</li></ul>'
        in: query
        name: fields
        type: string
      - description: 'Contact filter. <ul><li><b>contactid/s</b> - Time tracked by
          specified contacts<br>Example: 1,2,3</li><li><b>me</b> - Time tracked by
          requesting user</li><li><b>all</b> - All contacts (default)</li></ul>'
        in: query
        name: contacts
        type: string
      - description: Project ID or list of Project IDs (comma-separated)
        in: query
        name: projectid
        type: string
      - description: 'Item (task) ID or list of IDs (comma-separated). Alias: taskid'
        in: query
        name: itemid
        type: string
      - description: Alias for itemid parameter.
        in: query
        name: taskid
        type: string
      - description: Company ID or list of Company IDs (comma-separated)
        in: query
        name: companyid
        type: string
      - description: Project Category ID or list of Category IDs (comma-separated)
        in: query
        name: categoryid
        type: string
      - description: 'Time tracked on or after this date. Accepts yyyy-mm-dd or relative:
          -6d, -1w, -1m, -1y. Default: -6d'
        example: -6d
        in: query
        name: trackedfrom
        type: string
      - description: 'Time tracked on or before this date. Accepts yyyy-mm-dd or relative:
          +0d, +1w. Default: +0d'
        example: +0d
        in: query
        name: trackedto
        type: string
      - default: all
        description: Billable filter. <ul><li><b>billable</b> - Billable time only</li><li><b>nonbillable</b>
          - Non-billable time only</li><li><b>all</b> - All time (default)</li></ul>
        enum:
        - billable
        - nonbillable
        - all
        in: query
        name: billable
        type: string
      - default: all
        description: Filter by project status (activeworkstate). <ul><li><b>active</b>
          - Active projects only</li><li><b>complete</b> - Completed projects only</li><li><b>all</b>
          - All projects (default)</li></ul>
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - default: all
        description: Filter by item activeworkstate. <ul><li><b>active</b> - Active
          items only</li><li><b>complete</b> - Completed items only</li><li><b>deleted</b>
          - Deleted items only</li><li><b>all</b> - All items (default)</li></ul>
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: activeworkstate
        type: string
      - description: Alias for activeworkstate parameter.
        enum:
        - active
        - complete
        - deleted
        - all
        in: query
        name: status
        type: string
      - description: Search by notes. <ul><li><b>string</b> - Records where Notes
          contains string</li><li><b>!string</b> - Records where Notes does not contain
          string</li></ul>
        in: query
        name: searchnotes
        type: string
      - description: Search by item name. <ul><li><b>string</b> - Records where Item
          Name contains string</li><li><b>!string</b> - Records where Item Name does
          not contain string</li></ul>
        in: query
        name: searchitem
        type: string
      - description: Division ID (Advanced plan only)
        in: query
        name: divisionid
        type: string
      - description: Records modified on or after this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcfrom
        type: string
      - description: Records modified on or before this date (UTC). ISO8601 or relative
        in: query
        name: lastmodifiedutcto
        type: string
      - description: Records with ID greater than or equal to this value
        in: query
        name: idfrom
        type: string
      - description: Records with ID less than or equal to this value
        in: query
        name: idto
        type: string
      - description: List of Time Record IDs (comma-separated)
        in: query
        name: id
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - date
        - projectid
        - itemid
        - taskid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page Number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page Size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TimeListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Time Records
      tags:
      - time
    post:
      consumes:
      - application/json
      description: Create a new Time Record. Tracks time spent on an item by a contact.
      parameters:
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.TimeCreatePayload'
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Add Time Record
      tags:
      - time
  /time/{timeid}:
    delete:
      consumes:
      - application/json
      description: Delete an existing Time Record.
      parameters:
      - description: Time Record ID
        in: path
        name: timeid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Time Record
      tags:
      - time
    get:
      consumes:
      - application/json
      description: Returns details of a single Time Record by ID.
      parameters:
      - description: Time Record ID
        in: path
        name: timeid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TimeGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Time Record
      tags:
      - time
    put:
      consumes:
      - application/json
      description: Update an existing Time Record.
      parameters:
      - description: Time Record ID
        in: path
        name: timeid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.TimeUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Time Record
      tags:
      - time
  /time/contact:
    put:
      consumes:
      - application/json
      description: Reassigns the contact on one or more time log entries.
      parameters:
      - description: Time log IDs and new contact
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateTimelogContactRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Time Log Contact
      tags:
      - time
  /time/invoice:
    put:
      consumes:
      - application/json
      description: Updates the invoice item association on one or more time log entries.
      parameters:
      - description: Time log IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateTimelogInvoiceItemRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Time Log Invoice Item
      tags:
      - time
  /time/rate:
    put:
      consumes:
      - application/json
      description: Reassigns the hourly rate service on one or more time log entries.
      parameters:
      - description: Time log IDs and new hourly rate service
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateTimelogRateRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Time Log Rate
      tags:
      - time
  /time/start:
    post:
      consumes:
      - application/json
      description: Starts a running timer for the authenticated user against an item.
      parameters:
      - description: Item to start timer against
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.StartTimerRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Start Timer
      tags:
      - time
  /time/stop:
    post:
      consumes:
      - application/json
      description: Stops the currently running timer for the authenticated user.
      parameters:
      - description: Timer stop data
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.StopTimerRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Stop Timer
      tags:
      - time
  /time/uninvoice:
    put:
      consumes:
      - application/json
      description: Marks one or more time log entries as not invoiced.
      parameters:
      - description: Time log IDs
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.UpdateTimelogUnInvoiceRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Un-Invoice Time Logs
      tags:
      - time
  /timeallocations:
    delete:
      consumes:
      - application/json
      description: Deletes multiple Time Allocations by ID. The GraphQL setTimeAllocation
        mutation is called with deleted=true for each allocation.
      parameters:
      - description: IDs to delete
        in: body
        name: body
        required: true
        schema:
          $ref: '#/definitions/handlers.TimeAllocationDeletePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Time Allocations (batch)
      tags:
      - timeallocations
    get:
      consumes:
      - application/json
      description: Returns a list of Time Allocations based on the specified filters.
        The fields parameter allows you to choose which data fields to return for
        each allocation.
      parameters:
      - default: contact,item,project,time
        description: 'Comma-separated fields to return. Available: contact, item (or
          task), itemid (or taskid), project, time, labour, all'
        in: query
        name: fields
        type: string
      - description: Project ID or list of Project IDs (comma-separated)
        example: 1,2
        in: query
        name: projectid
        type: string
      - description: Contact ID or list of Contact IDs (comma-separated)
        example: 1,2
        in: query
        name: contactid
        type: string
      - description: 'Item (task) ID or list of IDs (comma-separated). Alias: taskid'
        example: 1,2
        in: query
        name: itemid
        type: string
      - description: Alias for itemid parameter.
        example: 1,2
        in: query
        name: taskid
        type: string
      - default: active
        description: Filter by project status
        enum:
        - active
        - complete
        - all
        in: query
        name: projectstatus
        type: string
      - description: Division ID (Advanced plan only)
        example: "1"
        in: query
        name: divisionid
        type: string
      - description: Allocations with ID >= this value
        in: query
        name: idfrom
        type: string
      - description: Allocations with ID <= this value
        in: query
        name: idto
        type: string
      - description: List of Time Allocation IDs (comma-separated)
        example: 1,2,3
        in: query
        name: id
        type: string
      - default: id
        description: Sort field
        enum:
        - id
        - contactid
        - itemid
        - taskid
        - projectid
        in: query
        name: sortby
        type: string
      - default: asc
        description: Sort order
        enum:
        - asc
        - desc
        in: query
        name: sortorder
        type: string
      - description: Page number (must be used with pagesize)
        example: 1
        in: query
        name: pagenumber
        type: integer
      - description: Page size (must be used with pagenumber)
        example: 50
        in: query
        name: pagesize
        type: integer
      - default: false
        description: Include total row count in meta (default false). Set to true
          to run the count query.
        in: query
        name: includetotalrows
        type: boolean
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TimeAllocationListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Time Allocations
      tags:
      - timeallocations
    post:
      consumes:
      - application/json
      description: Creates one or more Time Allocations. Accepts a JSON array of objects
        matching the SetTimeAllocationInput schema.
      parameters:
      - description: Array of time allocations to create
        in: body
        name: body
        required: true
        schema:
          items:
            $ref: '#/definitions/handlers.TimeAllocationCreatePayload'
          type: array
      produces:
      - application/json
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Create Time Allocations
      tags:
      - timeallocations
    put:
      consumes:
      - application/json
      description: Updates multiple Time Allocations in a single call. Each item in
        the array must include an id.
      parameters:
      - description: Array of time allocations to update (each must include id)
        in: body
        name: body
        required: true
        schema:
          items:
            $ref: '#/definitions/handlers.TimeAllocationUpdatePayload'
          type: array
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Time Allocations (batch)
      tags:
      - timeallocations
  /timeallocations/{timeallocationid}:
    delete:
      consumes:
      - application/json
      description: Deletes a single Time Allocation by ID.
      parameters:
      - description: Time Allocation ID
        in: path
        name: timeallocationid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Delete Time Allocation
      tags:
      - timeallocations
    get:
      consumes:
      - application/json
      description: Returns details of a single Time Allocation.
      parameters:
      - description: Time Allocation ID
        in: path
        name: timeallocationid
        required: true
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.TimeAllocationGetResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Get Time Allocation
      tags:
      - timeallocations
    put:
      consumes:
      - application/json
      description: Updates an existing Time Allocation.
      parameters:
      - description: Time Allocation ID
        in: path
        name: timeallocationid
        required: true
        type: integer
      - description: Request body
        in: body
        name: body
        schema:
          $ref: '#/definitions/handlers.TimeAllocationUpdatePayload'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/models.SuccessResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/models.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/models.ErrorResponse'
      security:
      - BearerAuth: []
      - ApiKeyAuth: []
      summary: Update Time Allocation
      tags:
      - timeallocations
schemes:
- https
securityDefinitions:
  ApiKeyAuth:
    description: 'API Key authentication. Format: "xxxx-xxxx-xxxx-xxxx-PWFxxxx"'
    in: header
    name: apikey
    type: apiKey
  BearerAuth:
    description: 'JWT Bearer token. Format: "Bearer <token>"'
    in: header
    name: Authorization
    type: apiKey
swagger: "2.0"
