> ## Documentation Index
> Fetch the complete documentation index at: https://docs.onboardme.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Get proposal by key

> Loads one proposal by **`key`**, including full detail: **services** (prices, quantities, packages), **invoices** / **recurringBillingSetups**, **xpmJobs**, **fyiJobs**, signatories, and clients.

Prefer **GET `/api/v1/proposals/{key}/pricing`** when you only need previous pricing, billing, and jobs (smaller payload for replicate/duplicate).

**`key`** is the proposal identifier returned by **GET `/api/v1/proposals/list`**.

**404:** Unknown key or proposal outside your practice.

**429:** Rate limit exceeded.

export function DensityStyles() {
  return <style>{`#page-title{font-size:1.5rem!important;line-height:1.25!important;letter-spacing:-.02em;margin-bottom:.4rem!important}#content-area{font-size:.9375rem;line-height:1.55}#content-area p{margin-top:.55em;margin-bottom:.55em}#api-playground-input,#request-example,#response-example{font-size:.8125rem}api-section-heading-title{font-size:1.5rem!important;line-height:1.25!important}api-section-heading{margin-bottom:.5rem}field{padding-top:.35rem;padding-bottom:.35rem;font-size:.875rem}tryit-button{font-size:.8rem}`}</style>;
}

<DensityStyles />


## OpenAPI

````yaml GET /api/v1/proposals/{key}
openapi: 3.0.4
info:
  title: OnboardMe External API
  description: "Partner integration API for OnboardMe. All routes are under `/api/v1/…` on your **regional** API host.\r\n\r\n---\r\n\r\n## Regional base URLs\r\n\r\nUse the host that matches where the practice is hosted (a practice is tied to one region).\r\n\r\n| Region | Base URL |\r\n| ------ | -------- |\r\n| Australia & New Zealand | `https://anzapi.onboardme.app` |\r\n| United Kingdom | `https://ukapi.onboardme.app` |\r\n| South Africa | `https://zaapi.onboardme.app` |\r\n\r\nIn your HTTP client, pick the matching **Server** / base URL (or set `baseUrl` to one of the URLs above).\r\n\r\nExample: `GET https://ukapi.onboardme.app/api/v1/auth/validate`\r\n\r\n---\r\n\r\n## Authentication\r\n\r\n**Production integrations (recommended):** send both headers on every request:\r\n\r\n- **`X-OM-Auth-ID`** — Client ID (GUID from OnboardMe practice settings)\r\n- **`X-OM-Auth-Key`** — Client secret paired with that Client ID\r\n\r\n**Postman / Swagger Try it out:** use **Authorize** (HTTP Basic) with **Client ID** as the username and **Client secret** as the password. In Postman, set Basic Auth **once on the collection** so every request inherits it — you do not need auth on each request or two separate header fields.\r\n\r\nHTTPS only. Credentials are scoped to one practice; this API does not use end-user passwords.\r\n\r\n---\r\n\r\n## Partner onboarding\r\n\r\n1. Obtain **Client ID** and **secret** from the practice administrator (OnboardMe).\r\n2. Select the **correct regional base URL** (ANZ, UK, or ZA); practices do not span regions.\r\n3. Call `GET /api/v1/auth/validate` to confirm access and read `canWrite` before using any write endpoint.\r\n4. Run an initial **full** import, then use `lastUpdated` on list endpoints for **incremental** sync.\r\n5. On **429 Too Many Requests**, honour `Retry-After` and backoff; avoid polling faster than you need.\r\n\r\n---\r\n\r\n## Pagination and sync\r\n\r\nList endpoints support optional `pageNumber` (1-based, up to 10000) and `lastUpdated` (UTC). Use `lastUpdated` for incremental sync: only rows changed on or after that instant. `lastUpdated` must not be in the future.\r\n\r\n---\r\n\r\n## Rate limits\r\n\r\nPer Client ID (default: 60/minute, 1000/hour, 10000/day). **429** responses include JSON details and headers: `Retry-After`, `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`.\r\n\r\n---\r\n\r\n## Write access\r\n\r\nCreating or updating data requires `canWrite: true` from `/api/v1/auth/validate`. Read-only clients get **403** on write routes.\r\n\r\nLead endpoints under **`/api/v1/leads`** support listing, detail, notes, create, and **convert-to-client** (promote a lead to an Active client).\r\n\r\n**Contacts** (`/api/v1/contacts/list` and `/api/v1/entities/{entityKey}/contacts`) expose people linked to clients — list, create, and update.\r\n\r\n**ID verifications** — **`POST /api/v1/id-verifications/send`** starts identity verification (optionally with AML via **`includeAml`**). **`POST /api/v1/id-verifications/aml-checks`** runs a standalone **standard** or **extensive** AML screening on an existing client (`entityKey`). Download a verification certificate PDF with **`GET /api/v1/id-verifications/entities/{entityKey}/certificate`**.\r\n\r\n**Onboarding documents** — **`GET /api/v1/onboardings/{key}/documents`** lists requirements per client entity (`isUploaded` / `isBypassed`). Download one file via a short-lived signed S3 URL: **`GET …/entities/{entityOnboardingId}/documents/{documentId}`**. Download all uploaded files as a zip: **`GET …/entities/{entityOnboardingId}/documents/zip`**.\r\n\r\n**Bills** — **`GET /api/v1/bills/list`** lists invoices by **bill date** range (`startDate` / `endDate`). **`GET /api/v1/bills/{billingId}`** returns detail including ledger fields (`externalId`, `externalNumber`, `externalUrl`). **`GET /api/v1/bills/{billingId}/pdf`** downloads the OnboardMe invoice PDF. **`POST /api/v1/bills`** creates an **adhoc** bill for an Active client entity only (no engagement / onboarding entity link; requires `canWrite`; does **not** push to Xero — stores `sendBill` / `syncNow`). When Xero is connected, lines need a revenue account (`extAccountID`) or sale item plus tax (`extTaxID`); use **`GET /api/v1/bills/ledger/status|accounts|tax-rates|branding-themes`**.\r\n\r\n**Proposals** — List a client's proposals with **`GET /api/v1/proposals/list?entityKey=`**. Load previous **services, invoices, recurring billings, and jobs** via **`GET /api/v1/proposals/{key}/pricing`** (or full **`GET /api/v1/proposals/{key}`**). **`POST /api/v1/proposals/{key}/duplicate`** copies pricing, billings, and jobs into a new draft. **`POST /api/v1/proposals/{key}/renew`** does the same and marks the original Renewed (**`GET …/renew-preview`** first for signatory choice). **`POST /api/v1/proposals/from-template`** creates from a saved template. **`POST /api/v1/proposals`** creates an **adhoc** proposal with caller-supplied **services**, optional **XPM jobs**, **FYI jobs**, and **billings**. Catalogs: **`GET /api/v1/proposals/services`**, **`…/xpm-job-templates`**, **`…/xpm-job-categories`**, **`…/xpm-staff`**, **`…/fyi-job-templates`**, **`…/fyi-job-states`**.\r\n\r\n**Recurring billing** — **`GET /api/v1/recurring-billing/list`**, **`GET /api/v1/recurring-billing/{recurringBillingId}`**, and **`GET …/runs`** for schedule list, detail, and generated-run history. Ledger invoice numbers/URLs appear on generated bills, not on the schedule itself.\r\n\r\n---\r\n\r\n## Outbound webhooks\r\n\r\nRegister a subscriber URL with **`POST /api/v1/webhooks`** (requires `canWrite`). Supported event keys are listed at **`GET /api/v1/webhooks/events`** (e.g. `proposal.accepted`, `eform.submitted`). One subscription per event; repeat subscribe with the same URL for multiple events.\r\n\r\n**Subscribe response (`201`):** `{ \"id\", \"webhookSecret\" }` — store `webhookSecret` immediately; it is **not** returned again on list/load.\r\n\r\n**Deliveries:** OnboardMe `POST`s JSON to your URL. Each request includes:\r\n\r\n| Header | Description |\r\n| ------ | ------------- |\r\n| `X-Om-Event` | Event key (e.g. `proposal.accepted`) |\r\n| `X-Om-Event-Id` | Unique idempotency key for this event |\r\n| `X-Om-Timestamp` | Unix time (seconds, UTC) used when signing |\r\n| `X-Om-Signature` | `sha256=<hex>` HMAC (see below) |\r\n\r\n**Signature verification (recommended on your server):**\r\n\r\n1. Read the **raw** request body bytes (do not re-serialize JSON).\r\n2. Build `canonical = {X-Om-Timestamp} + \".\" + {rawBody}`.\r\n3. Compute `expected = \"sha256=\" + HMAC_SHA256_UTF8(webhookSecret, canonical)` (hex **lowercase**).\r\n4. Compare `expected` to `X-Om-Signature` using a constant-time comparison; reject on mismatch.\r\n\r\nThe delivery JSON schema is documented as **`ApiWebhookDeliveryEventDTO`** in Schemas (see **Webhooks** operations). Test deliveries: **`POST /api/v1/webhooks/{id}/test`**.\r\n\r\n---\r\n\r\n## Errors\r\n\r\n- **400** — validation (`message` in body).\r\n- **401** — bad or missing credentials.\r\n- **404** — resource not in the practice (`message`).\r\n\r\nSchemas below include **illustrative** example values; live responses use your data."
  contact:
    name: OnboardMe Support
    email: support@onboardme.app
  version: v1
servers:
  - url: https://anzapi.onboardme.app
    description: Australia & New Zealand — ANZ-hosted practices
  - url: https://ukapi.onboardme.app
    description: United Kingdom — UK-hosted practices
  - url: https://zaapi.onboardme.app
    description: South Africa — ZA-hosted practices
security:
  - ApiClientCredentials: []
paths:
  /api/v1/proposals/{key}:
    get:
      tags:
        - Proposals
      summary: Get proposal by key
      description: "Loads one proposal by **`key`**, including full detail: **services** (prices, quantities, packages), **invoices** / **recurringBillingSetups**, **xpmJobs**, **fyiJobs**, signatories, and clients.\r\n\r\nPrefer **GET `/api/v1/proposals/{key}/pricing`** when you only need previous pricing, billing, and jobs (smaller payload for replicate/duplicate).\r\n\r\n**`key`** is the proposal identifier returned by **GET `/api/v1/proposals/list`**.\r\n\r\n**404:** Unknown key or proposal outside your practice.\r\n\r\n**429:** Rate limit exceeded."
      parameters:
        - name: key
          in: path
          description: Proposal key (identifier).
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: OK
          content:
            text/plain:
              schema:
                $ref: >-
                  #/components/schemas/Application.Engagements.DataObjects.EngagementDTO
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/Application.Engagements.DataObjects.EngagementDTO
            text/json:
              schema:
                $ref: >-
                  #/components/schemas/Application.Engagements.DataObjects.EngagementDTO
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too Many Requests
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Internal Server Error
components:
  schemas:
    Application.Engagements.DataObjects.EngagementDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        practiceID:
          type: integer
          format: int32
        lengthID:
          type: integer
          format: int32
        statusID:
          type: integer
          format: int32
        entityID:
          type: integer
          format: int32
          nullable: true
        currencyID:
          type: integer
          format: int32
        approverID:
          type: integer
          format: int32
          nullable: true
        onboardingKey:
          type: string
          format: uuid
          nullable: true
        ethicalLetterKey:
          type: string
          format: uuid
          nullable: true
        serviceGrouping:
          type: integer
          format: int32
          nullable: true
        sendEthicalWhen:
          type: integer
          format: int32
          nullable: true
        name:
          type: string
          nullable: true
        note:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
        startOnAcceptance:
          type: boolean
        endDate:
          type: string
          format: date-time
          nullable: true
        expiryDate:
          type: string
          format: date-time
          nullable: true
        requestPaymentDetails:
          type: boolean
        paymentDetailsType:
          type: integer
          format: int32
        requiresApproval:
          type: boolean
        requiresMultipleAcceptance:
          type: boolean
        isNewClient:
          type: boolean
          nullable: true
        newClientName:
          type: string
          nullable: true
        newClientSurname:
          type: string
          nullable: true
        newClientEmail:
          type: string
          nullable: true
        newClientBusinessNo:
          type: string
          nullable: true
        newClientAddress:
          type: string
          nullable: true
        onboardAfterAcceptance:
          type: boolean
          nullable: true
        sendEthicalLetter:
          type: boolean
          nullable: true
        createXpmJobs:
          type: boolean
        createKarbonWorkItems:
          type: boolean
        businessSignatory:
          type: integer
          format: int32
          nullable: true
        createFreeAgentProjects:
          type: boolean
        createGSTasks:
          type: boolean
        createFYIJobs:
          type: boolean
        createChecklist:
          type: boolean
        includeCdd:
          type: boolean
        sendForm:
          type: boolean
        formKey:
          type: string
          format: uuid
          nullable: true
        onboardingSendForm:
          type: boolean
        onboardingFormKey:
          type: string
          format: uuid
          nullable: true
        onboardingGroupID:
          type: integer
          format: int32
          nullable: true
        approvedOn:
          type: string
          format: date-time
          nullable: true
        sentOn:
          type: string
          format: date-time
          nullable: true
        sentBy:
          type: integer
          format: int32
          nullable: true
        reminderCount:
          type: integer
          format: int32
        createdBy:
          type: integer
          format: int32
        createdOn:
          type: string
          format: date-time
        updatedBy:
          type: integer
          format: int32
          nullable: true
        updatedOn:
          type: string
          format: date-time
          nullable: true
        key:
          type: string
          format: uuid
        terms:
          type: integer
          format: int32
        termsDetailsOverride:
          type: string
          nullable: true
        createBills:
          type: boolean
        recurringBilling:
          type: integer
          format: int32
        payerID:
          type: string
          nullable: true
        xglClientUUID:
          type: string
          format: uuid
          nullable: true
        refNo:
          type: string
          nullable: true
        statusName:
          type: string
          nullable: true
        clientName:
          type: string
          nullable: true
        currencyName:
          type: string
          nullable: true
        sendEthicalOption:
          type: string
          nullable: true
        baseUrl:
          type: string
          nullable: true
        entityName:
          type: string
          nullable: true
        entitySurname:
          type: string
          nullable: true
        entityMobile:
          type: string
          nullable: true
        entityEmail:
          type: string
          nullable: true
        welcomePDF:
          type: boolean
        pdfid:
          type: integer
          format: int32
          nullable: true
        sendSMS:
          type: boolean
        suppressClientDelivery:
          type: boolean
        stpid:
          type: integer
          format: int32
          nullable: true
        stpDetailsOverride:
          type: string
          nullable: true
        document1Name:
          type: string
          nullable: true
        document1ID:
          type: integer
          format: int32
        document1DetailsOverride:
          type: string
          nullable: true
        document2Name:
          type: string
          nullable: true
        document2ID:
          type: integer
          format: int32
        document2DetailsOverride:
          type: string
          nullable: true
        document3Name:
          type: string
          nullable: true
        document3ID:
          type: integer
          format: int32
        document3DetailsOverride:
          type: string
          nullable: true
        document4Name:
          type: string
          nullable: true
        document4ID:
          type: integer
          format: int32
        document4DetailsOverride:
          type: string
          nullable: true
        package1Name:
          type: string
          nullable: true
        package1Price:
          type: number
          format: double
        package2Name:
          type: string
          nullable: true
        package2Price:
          type: number
          format: double
        package3Name:
          type: string
          nullable: true
        package3Price:
          type: number
          format: double
        packageChosen:
          type: integer
          format: int32
          nullable: true
        packageChosenBy:
          type: string
          nullable: true
        packageText:
          type: string
          nullable: true
        popularPackage:
          type: integer
          format: int32
          nullable: true
        showServiceMenu:
          type: boolean
        additionalServices:
          type: string
          nullable: true
        emailSubject:
          type: string
          nullable: true
        emailContent:
          type: string
          nullable: true
        packageTexts:
          type: object
          additionalProperties:
            type: string
          nullable: true
        services:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.EngagementDetails.DataObjects.EngagementDetailsDTO
          nullable: true
        signatories:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.EngagementSignatures.DataObjects.EngagementSignatureDTO
          nullable: true
        xpmJobs:
          type: array
          items:
            $ref: '#/components/schemas/Application.Integration.DataObjects.XpmJobDTO'
          nullable: true
        karbonWorkItems:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.Integration.DataObjects.Karbon.KarbonWorkItemDTO
          nullable: true
        freeAgentProjects:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.Integration.DataObjects.FreeAgent.FreeAgentProjectEntity
          nullable: true
        fyiJobs:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.Integration.DataObjects.FYI.FyiJobDTO
          nullable: true
        onboardingClients:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.EntityOnboarding.DataObjects.EntityOnboardingInfoDTO
          nullable: true
        clients:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.Engagements.DataObjects.EngagementClientDTO
          nullable: true
        onboardingRecipients:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.OnboardingRecipient.DataObjects.OnboardingRecipientDTO
          nullable: true
        ethicalClearance:
          $ref: >-
            #/components/schemas/Application.EthicalLetters.DataObjects.EthicalLetterSaveDTO
        form:
          $ref: '#/components/schemas/Application.Forms.DataObjects.FormDTO'
        onboardingForm:
          $ref: '#/components/schemas/Application.Forms.DataObjects.FormDTO'
        gsTasks:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.Integration.DataObjects.GreatSoft.GreatSoftTaskDTO
          nullable: true
        invoices:
          type: array
          items:
            $ref: '#/components/schemas/Application.Billing.DataObjects.BillingDTO'
          nullable: true
        recurringBillingSetup:
          $ref: >-
            #/components/schemas/Application.RecurringBilling.DataObjects.RecurringBillingDTO
        recurringBillingSetups:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.RecurringBilling.DataObjects.RecurringBillingDTO
          nullable: true
        checklist:
          $ref: '#/components/schemas/Application.Checklists.DataObjects.ChecklistDTO'
        updateStep:
          type: string
          nullable: true
        saveResponseMode:
          type: string
          nullable: true
        saveIncompleteMessage:
          type: string
          nullable: true
        refreshSubscriptionCounts:
          type: boolean
        coverPageID:
          type: integer
          format: int32
          nullable: true
      additionalProperties: false
      example:
        key: 8f9e2b1c-3d4a-5e6f-7890-abcdef012345
        id: 12450
        practiceID: 8801
        statusID: 3
        name: FY25 — Corporate tax proposal
        startDate: '2025-04-01T00:00:00Z'
        endDate: '2025-06-30T00:00:00Z'
        expiryDate: '2025-05-15T00:00:00Z'
    Microsoft.AspNetCore.Mvc.ProblemDetails:
      type: object
      properties:
        type:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        status:
          type: integer
          format: int32
          nullable: true
        detail:
          type: string
          nullable: true
        instance:
          type: string
          nullable: true
      additionalProperties: {}
    Application.EngagementDetails.DataObjects.EngagementDetailsDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        engagementID:
          type: integer
          format: int32
        engagementClientID:
          type: integer
          format: int64
          nullable: true
        clientRowKey:
          type: string
          nullable: true
        serviceID:
          type: integer
          format: int32
        parentServiceID:
          type: integer
          format: int32
          nullable: true
        pricingTypeDetailID:
          type: integer
          format: int32
        jobTemplateID:
          type: integer
          format: int32
          nullable: true
        serviceName:
          type: string
          nullable: true
        serviceDetail:
          type: string
          nullable: true
        price:
          type: number
          format: double
        rangeMin:
          type: number
          format: double
          nullable: true
        rangeMax:
          type: number
          format: double
          nullable: true
        quantity:
          type: number
          format: double
          nullable: true
        taxAmount:
          type: number
          format: double
        discountPerc:
          type: number
          format: double
        discountAmount:
          type: number
          format: double
        orderID:
          type: integer
          format: int32
        packageNumber:
          type: integer
          format: int32
        frequencyID:
          type: integer
          format: int32
        designatedService:
          type: boolean
        isOptional:
          type: boolean
        optionalChosen:
          type: integer
          format: int32
        subscriptionID:
          type: integer
          format: int64
          nullable: true
        frequency:
          type: string
          nullable: true
        pricingTypeName:
          type: string
          nullable: true
        parentServiceName:
          type: string
          nullable: true
        customHTML:
          type: string
          nullable: true
      additionalProperties: false
    Application.EngagementSignatures.DataObjects.EngagementSignatureDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        engagementID:
          type: integer
          format: int32
        orderID:
          type: integer
          format: int32
        isSigned:
          type: boolean
        signature:
          type: string
          nullable: true
        signerName:
          type: string
          nullable: true
        signerSurname:
          type: string
          nullable: true
        signerEmail:
          type: string
          nullable: true
        signerMobile:
          type: string
          nullable: true
        isOnboardingTarget:
          type: boolean
          nullable: true
        marketing:
          type: integer
          format: int32
          nullable: true
        ipAddress:
          type: string
          nullable: true
        termsAccepted:
          type: boolean
        signedOn:
          type: string
          format: date-time
          nullable: true
        note:
          type: string
          nullable: true
        createdBy:
          type: integer
          format: int32
        createdOn:
          type: string
          format: date-time
        updatedBy:
          type: integer
          format: int32
          nullable: true
        updatedOn:
          type: string
          format: date-time
          nullable: true
        key:
          type: string
          format: uuid
      additionalProperties: false
    Application.Integration.DataObjects.XpmJobDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        integrationID:
          type: integer
          format: int32
        engagementID:
          type: integer
          format: int32
        entityID:
          type: integer
          format: int32
          nullable: true
        isOnboardingEntity:
          type: boolean
        xpmID:
          type: string
          nullable: true
        uuid:
          type: string
          format: uuid
          nullable: true
        name:
          type: string
          nullable: true
        clientUUID:
          type: string
          format: uuid
          nullable: true
        description:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
        dueDate:
          type: string
          format: date-time
        templateUUID:
          type: string
          format: uuid
          nullable: true
        categoryID:
          type: string
          format: uuid
          nullable: true
        refNo:
          maxLength: 50
          type: string
          nullable: true
        partnerUUID:
          type: string
          format: uuid
          nullable: true
        managerUUID:
          type: string
          format: uuid
          nullable: true
        staffUUID:
          type: string
          nullable: true
        budget:
          type: number
          format: double
        taskIDs:
          type: array
          items:
            type: integer
            format: int32
          nullable: true
        tasks:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.Integration.DataObjects.XpmJobTaskDTO
          nullable: true
      additionalProperties: false
    Application.Integration.DataObjects.Karbon.KarbonWorkItemDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
        integrationID:
          type: integer
          format: int32
        engagementID:
          type: integer
          format: int32
        entityID:
          type: integer
          format: int32
          nullable: true
        isOnboardingEntity:
          type: boolean
        karbonWorkTemplateID:
          type: integer
          format: int64
          nullable: true
        workTemplateKey:
          type: string
          nullable: true
        workItemKey:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        clientKey:
          type: string
          nullable: true
        clientType:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
          nullable: true
        dueDate:
          type: string
          format: date-time
          nullable: true
        deadlineDate:
          type: string
          format: date-time
          nullable: true
        workType:
          type: string
          nullable: true
        primaryStatus:
          type: string
          nullable: true
        secondaryStatus:
          type: string
          nullable: true
        assigneeEmailAddress:
          type: string
          nullable: true
        userRoleAssignmentsJson:
          type: string
          nullable: true
        deployedOn:
          type: string
          format: date-time
          nullable: true
        createdOn:
          type: string
          format: date-time
        updatedOn:
          type: string
          format: date-time
      additionalProperties: false
    Application.Integration.DataObjects.FreeAgent.FreeAgentProjectEntity:
      type: object
      properties:
        id:
          type: integer
          format: int64
        integrationID:
          type: integer
          format: int32
        engagementID:
          type: integer
          format: int32
        projectURL:
          type: string
          nullable: true
        contactURL:
          type: string
          nullable: true
        name:
          type: string
          nullable: true
        contactName:
          type: string
          nullable: true
        budget:
          type: number
          format: double
        budgetUnits:
          type: string
          nullable: true
        normalBillingRate:
          type: number
          format: double
          nullable: true
        hoursPerDay:
          type: number
          format: double
          nullable: true
        billingPeriod:
          type: string
          nullable: true
        currency:
          type: string
          nullable: true
        isIr35:
          type: boolean
        usesProjectInvoiceSequence:
          type: boolean
        includeUnbilledTimeInProfitability:
          type: boolean
        isDeletable:
          type: boolean
        status:
          type: string
          nullable: true
        createdAt:
          type: string
          format: date-time
          nullable: true
        startsOn:
          type: string
          format: date-time
          nullable: true
        endsOn:
          type: string
          format: date-time
          nullable: true
        systemCreatedOn:
          type: string
          format: date-time
        systemUpdatedOn:
          type: string
          format: date-time
      additionalProperties: false
    Application.Integration.DataObjects.FYI.FyiJobDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        practiceIntegrationID:
          type: integer
          format: int32
        engagementID:
          type: integer
          format: int32
        entityID:
          type: integer
          format: int32
          nullable: true
        isOnboardingEntity:
          type: boolean
        jobName:
          maxLength: 255
          type: string
          nullable: true
        sourceID:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        type:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
          nullable: true
        dueDate:
          type: string
          format: date-time
          nullable: true
        managerEmail:
          type: string
          nullable: true
        partnerEmail:
          type: string
          nullable: true
        fyiTemplateID:
          type: string
          nullable: true
        fyJobID:
          type: string
          nullable: true
      additionalProperties: false
    Application.EntityOnboarding.DataObjects.EntityOnboardingInfoDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        entityTypeID:
          type: integer
          format: int32
        entityName:
          type: string
          nullable: true
        entitySurname:
          type: string
          nullable: true
        isTaxEntity:
          type: boolean
        mustVerify:
          type: boolean
        verificationMethod:
          type: string
          nullable: true
        requireDocs:
          type: boolean
        requiredDocs:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.OnboardingDocuments.DataObjects.OnboardingDocumentCreateDTO
          nullable: true
        entityID:
          type: integer
          format: int32
          nullable: true
        entityEmail:
          type: string
          nullable: true
        entityMobile:
          type: string
          nullable: true
        requestAccFile:
          type: boolean
        accInviteName:
          type: string
          nullable: true
        canDelete:
          type: boolean
        tempKey:
          type: string
          nullable: true
        clientCode:
          type: string
          nullable: true
      additionalProperties: false
    Application.Engagements.DataObjects.EngagementClientDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
        engagementID:
          type: integer
          format: int32
        entityID:
          type: integer
          format: int32
        entityTypeID:
          type: integer
          format: int32
          nullable: true
        cddCaseID:
          type: integer
          format: int32
          nullable: true
        groupID:
          type: integer
          format: int32
          nullable: true
        clientLinkType:
          $ref: >-
            #/components/schemas/Application.Engagements.EngagementClientLinkType
        onboardingEntityID:
          type: integer
          format: int32
          nullable: true
        clientRowKey:
          type: string
          nullable: true
        mustVerify:
          type: boolean
        verificationMethod:
          type: string
          nullable: true
        verifierSignatureKey:
          type: string
          nullable: true
        idVerificationID:
          type: integer
          format: int32
          nullable: true
        isIdVerified:
          type: boolean
        idVerificationStatusID:
          type: integer
          format: int32
          nullable: true
        isOnboardingEntity:
          type: boolean
        isPrimaryClient:
          type: boolean
        includeEngagement:
          type: boolean
        orderID:
          type: integer
          format: int32
        clientName:
          type: string
          nullable: true
        clientOtherName:
          type: string
          nullable: true
        clientSurname:
          type: string
          nullable: true
        clientEmail:
          type: string
          nullable: true
        clientMobile:
          type: string
          nullable: true
        clientBusinessNo:
          type: string
          nullable: true
        clientAddress:
          type: string
          nullable: true
        entityPayerID:
          type: string
          nullable: true
      additionalProperties: false
    Application.OnboardingRecipient.DataObjects.OnboardingRecipientDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
        onboardingID:
          type: integer
          format: int32
        name:
          type: string
          nullable: true
        surname:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        mobile:
          type: string
          nullable: true
        sendSMS:
          type: boolean
        sendOrder:
          type: integer
          format: int32
        statusID:
          type: integer
          format: int32
        statusName:
          type: string
          nullable: true
        sentOn:
          type: string
          format: date-time
          nullable: true
        openedOn:
          type: string
          format: date-time
          nullable: true
        submittedOn:
          type: string
          format: date-time
          nullable: true
        key:
          type: string
          format: uuid
        signatureKey:
          type: string
          format: uuid
          nullable: true
        createdBy:
          type: integer
          format: int32
          nullable: true
        createdOn:
          type: string
          format: date-time
          nullable: true
        updatedBy:
          type: integer
          format: int32
          nullable: true
        updatedOn:
          type: string
          format: date-time
          nullable: true
        entityAccess:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.OnboardingRecipientAccess.DataObjects.OnboardingRecipientAccessDTO
          nullable: true
      additionalProperties: false
    Application.EthicalLetters.DataObjects.EthicalLetterSaveDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        accountantName:
          type: string
          nullable: true
        accountantEmail:
          type: string
          nullable: true
        clientName:
          type: string
          nullable: true
        ethicalLetterDetail:
          type: string
          nullable: true
        partnerID:
          type: integer
          format: int32
          nullable: true
        requireDocuments:
          type: boolean
        emailSubject:
          type: string
          nullable: true
        emailContent:
          type: string
          nullable: true
        baseURL:
          type: string
          nullable: true
        documentRequirements:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.EthicalLetterDocuments.DataObjects.EthicalLetterDocumentSaveDTO
          nullable: true
        selectedAttachments:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.EthicalLetterAttachmentLink.DataObjects.EthicalLetterAttachmentLinkSaveDTO
          nullable: true
        clients:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.EthicalLetterClients.DataObjects.EthicalLetterClientSaveDTO
          nullable: true
      additionalProperties: false
    Application.Forms.DataObjects.FormDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        key:
          type: string
          format: uuid
        practiceID:
          type: integer
          format: int32
        practiceKey:
          type: string
          nullable: true
        entityID:
          type: integer
          format: int32
          nullable: true
        statusID:
          type: integer
          format: int32
          nullable: true
        formTypeID:
          type: integer
          format: int32
          nullable: true
        stackKey:
          type: string
          format: uuid
          nullable: true
        stackSortOrder:
          type: integer
          format: int32
          nullable: true
        name:
          type: string
          nullable: true
        schema:
          nullable: true
        answerCount:
          type: integer
          format: int32
        reminderCount:
          type: integer
          format: int32
        recipientName:
          type: string
          nullable: true
        recipientEmail:
          type: string
          nullable: true
        recipientMobile:
          type: string
          nullable: true
        sendSMS:
          type: boolean
        code:
          type: string
          nullable: true
        emailSubject:
          type: string
          nullable: true
        emailContent:
          type: string
          nullable: true
        sentOn:
          type: string
          format: date-time
          nullable: true
        openedOn:
          type: string
          format: date-time
          nullable: true
        completedOn:
          type: string
          format: date-time
          nullable: true
        cancelledOn:
          type: string
          format: date-time
          nullable: true
        createdBy:
          type: integer
          format: int32
        createdOn:
          type: string
          format: date-time
        updatedBy:
          type: integer
          format: int32
          nullable: true
        updatedOn:
          type: string
          format: date-time
          nullable: true
        statusName:
          type: string
          nullable: true
        practiceName:
          type: string
          nullable: true
        practicePrimaryColor:
          type: string
          nullable: true
        practiceSecondaryColor:
          type: string
          nullable: true
        practiceCountryCode:
          type: string
          nullable: true
        practiceDocLogoAlign:
          type: string
          nullable: true
        practiceEmailLogoAlign:
          type: string
          nullable: true
        practiceWebsite:
          type: string
          nullable: true
        practiceTelephone:
          type: string
          nullable: true
      additionalProperties: false
    Application.Integration.DataObjects.GreatSoft.GreatSoftTaskDTO:
      type: object
      properties:
        pkTaskID:
          type: integer
          format: int32
        fkEngagementID:
          type: integer
          format: int32
        entityID:
          type: integer
          format: int32
          nullable: true
        isOnboardingEntity:
          type: boolean
        allowTSE:
          type: integer
          format: int32
        clientCode:
          type: string
          nullable: true
        currCodeID:
          type: string
          nullable: true
        groupCode:
          type: string
          nullable: true
        officeCode:
          type: string
          nullable: true
        servLineCode:
          type: string
          nullable: true
        taskCode:
          type: string
          nullable: true
        taskDesc:
          type: string
          nullable: true
        taskDateOpen:
          type: string
          format: date-time
        taskManager:
          type: string
          nullable: true
        taskPartner:
          type: string
          nullable: true
        billingManagerID:
          type: string
          nullable: true
        extTaskID:
          type: string
          nullable: true
      additionalProperties: false
    Application.Billing.DataObjects.BillingDTO:
      type: object
      properties:
        billingID:
          type: integer
          format: int32
        practiceID:
          type: integer
          format: int32
        engagementID:
          type: integer
          format: int32
        engagementName:
          type: string
          nullable: true
        engagementStatusID:
          type: integer
          format: int32
          nullable: true
        isEngagementFinalised:
          type: boolean
        entityID:
          type: integer
          format: int32
        isOnboardingEntity:
          type: boolean
        entityName:
          type: string
          nullable: true
        billDate:
          type: string
          format: date
        dueDate:
          type: string
          format: date
        billNumber:
          type: string
          nullable: true
        billAmount:
          type: number
          format: double
        billTax:
          type: number
          format: double
        billTotal:
          type: number
          format: double
        billDetails:
          type: string
          nullable: true
        currencyID:
          type: integer
          format: int32
        paymentTotal:
          type: number
          format: double
        refNo:
          type: string
          nullable: true
        billNow:
          type: integer
          format: int32
        syncNow:
          type: boolean
        sendBill:
          type: boolean
        billPercent:
          type: integer
          format: int32
        packageNumber:
          type: integer
          format: int32
          nullable: true
        externalID:
          type: string
          nullable: true
        externalNumber:
          type: string
          nullable: true
        externalURL:
          type: string
          nullable: true
        syncAttemptCount:
          type: integer
          format: int32
        syncFailedReason:
          type: string
          nullable: true
        externalDetails:
          type: string
          nullable: true
        brandingThemeID:
          type: string
          nullable: true
        createdBy:
          type: integer
          format: int32
        createdOn:
          type: string
          format: date-time
        updatedBy:
          type: integer
          format: int32
        updatedOn:
          type: string
          format: date-time
        cancelledOn:
          type: string
          format: date-time
          nullable: true
        cancelledBy:
          type: integer
          format: int32
          nullable: true
        billingDetails:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.BillingDetails.DataObjects.BillingDetailsDTO
          nullable: true
      additionalProperties: false
    Application.RecurringBilling.DataObjects.RecurringBillingDTO:
      type: object
      properties:
        recurringBillingID:
          type: integer
          format: int64
        practiceID:
          type: integer
          format: int32
        engagementID:
          type: integer
          format: int32
          nullable: true
        entityID:
          type: integer
          format: int32
        isOnboardingEntity:
          type: boolean
        entityName:
          type: string
          nullable: true
        currencyID:
          type: integer
          format: int32
        frequency:
          type: string
          nullable: true
        startDate:
          type: string
          format: date
        endDate:
          type: string
          format: date
          nullable: true
        nextRunDate:
          type: string
          format: date
        billAmount:
          type: number
          format: double
        billTax:
          type: number
          format: double
        billTotal:
          type: number
          format: double
        billDetails:
          type: string
          nullable: true
        packageNumber:
          type: integer
          format: int32
          nullable: true
        externalDetails:
          type: string
          nullable: true
        brandingThemeID:
          type: string
          nullable: true
        dueDays:
          type: integer
          format: int32
        refNo:
          type: string
          nullable: true
        isActive:
          type: boolean
        sendBill:
          type: boolean
        billNow:
          type: integer
          format: int32
        isSubscriptionRecoup:
          type: boolean
        linkedEntitySubscriptionID:
          type: integer
          format: int64
          nullable: true
        createdBy:
          type: integer
          format: int32
        createdOn:
          type: string
          format: date-time
        updatedBy:
          type: integer
          format: int32
        updatedOn:
          type: string
          format: date-time
        details:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.RecurringBilling.DataObjects.RecurringBillingDetailDTO
          nullable: true
      additionalProperties: false
    Application.Checklists.DataObjects.ChecklistDTO:
      type: object
      properties:
        checklistId:
          type: integer
          format: int32
        practiceId:
          type: integer
          format: int32
        entityId:
          type: integer
          format: int32
          nullable: true
        checklistName:
          type: string
          nullable: true
        entityName:
          type: string
          nullable: true
        engagementId:
          type: integer
          format: int32
          nullable: true
        engagementName:
          type: string
          nullable: true
        typeId:
          type: integer
          format: int32
        typeName:
          type: string
          nullable: true
        statusId:
          type: integer
          format: int32
        statusName:
          type: string
          nullable: true
        signOffRequired:
          type: boolean
        signedOffUser:
          type: integer
          format: int32
          nullable: true
        signedOffOn:
          type: string
          format: date-time
          nullable: true
        checklistNotes:
          type: string
          nullable: true
        createdBy:
          type: integer
          format: int32
          nullable: true
        createdByName:
          type: string
          nullable: true
        createdOn:
          type: string
          format: date-time
          nullable: true
        updatedBy:
          type: integer
          format: int32
          nullable: true
        updatedByName:
          type: string
          nullable: true
        updatedOn:
          type: string
          format: date-time
          nullable: true
        details:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.Checklists.DataObjects.ChecklistDetailsDTO
          nullable: true
      additionalProperties: false
    Application.Integration.DataObjects.XpmJobTaskDTO:
      type: object
      properties:
        jobTaskID:
          type: integer
          format: int32
        taskID:
          type: integer
          format: int32
        description:
          type: string
          nullable: true
        label:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
          nullable: true
        dueDate:
          type: string
          format: date-time
          nullable: true
        estimatedMinutes:
          type: string
          nullable: true
        orderID:
          type: integer
          format: int32
      additionalProperties: false
    Application.OnboardingDocuments.DataObjects.OnboardingDocumentCreateDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        entityOnboardingID:
          type: integer
          format: int32
        documentRequested:
          type: string
          nullable: true
        externalID:
          type: string
          nullable: true
      additionalProperties: false
    Application.Engagements.EngagementClientLinkType:
      enum:
        - 0
        - 1
        - 2
        - 3
      type: integer
      format: int32
    Application.OnboardingRecipientAccess.DataObjects.OnboardingRecipientAccessDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
        recipientID:
          type: integer
          format: int64
        entityOnboardingID:
          type: integer
          format: int32
        canEdit:
          type: boolean
        createdBy:
          type: integer
          format: int32
          nullable: true
        createdOn:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
    Application.EthicalLetterDocuments.DataObjects.EthicalLetterDocumentSaveDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        ethicalLetterID:
          type: integer
          format: int32
        documentRequested:
          type: string
          nullable: true
        documentUploaded:
          type: string
          nullable: true
        isUploaded:
          type: boolean
        bypassed:
          type: boolean
        bypassReason:
          type: string
          nullable: true
      additionalProperties: false
    Application.EthicalLetterAttachmentLink.DataObjects.EthicalLetterAttachmentLinkSaveDTO:
      type: object
      properties:
        attachmentID:
          type: integer
          format: int64
        sortOrder:
          type: integer
          format: int32
      additionalProperties: false
    Application.EthicalLetterClients.DataObjects.EthicalLetterClientSaveDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
        ethicalLetterID:
          type: integer
          format: int32
        ethicalLetterKey:
          type: string
          format: uuid
        entityID:
          type: integer
          format: int32
        engagementClientID:
          type: integer
          format: int64
          nullable: true
        isOnboardingEntity:
          type: boolean
        clientRowKey:
          type: string
          nullable: true
        clientName:
          type: string
          nullable: true
        taxNumber:
          type: string
          nullable: true
        businessNumber:
          type: string
          nullable: true
      additionalProperties: false
    Application.BillingDetails.DataObjects.BillingDetailsDTO:
      type: object
      properties:
        billingDetailID:
          type: integer
          format: int32
        billingID:
          type: integer
          format: int32
        billAmount:
          type: number
          format: double
        billTax:
          type: number
          format: double
        billTotal:
          type: number
          format: double
        narration:
          type: string
          nullable: true
        extItemID:
          type: integer
          format: int32
        extAccountID:
          type: integer
          format: int64
          nullable: true
        extTaxID:
          type: integer
          format: int32
          nullable: true
        fieldOne:
          type: string
          nullable: true
        fieldTwo:
          type: string
          nullable: true
        orderID:
          type: integer
          format: int32
        serviceID:
          type: integer
          format: int32
          nullable: true
      additionalProperties: false
    Application.RecurringBilling.DataObjects.RecurringBillingDetailDTO:
      type: object
      properties:
        recurringDetailID:
          type: integer
          format: int64
        recurringBillingID:
          type: integer
          format: int64
        billAmount:
          type: number
          format: double
        billTax:
          type: number
          format: double
        billTotal:
          type: number
          format: double
        narration:
          type: string
          nullable: true
        extItemID:
          type: integer
          format: int32
          nullable: true
        extAccountID:
          type: integer
          format: int64
          nullable: true
        extTaxID:
          type: integer
          format: int32
          nullable: true
        fieldOne:
          type: string
          nullable: true
        fieldTwo:
          type: string
          nullable: true
        orderID:
          type: integer
          format: int32
        serviceID:
          type: integer
          format: int32
          nullable: true
        entitySubscriptionID:
          type: integer
          format: int64
          nullable: true
        subscriptionName:
          type: string
          nullable: true
        entityName:
          type: string
          nullable: true
        subscriptionEntityID:
          type: integer
          format: int32
          nullable: true
        xpmJobID:
          type: string
          nullable: true
        xpmCostCode:
          type: string
          nullable: true
        xpmUnitCost:
          type: number
          format: double
          nullable: true
        xpmBillable:
          type: boolean
        xpmCostOnly:
          type: boolean
      additionalProperties: false
    Application.Checklists.DataObjects.ChecklistDetailsDTO:
      type: object
      properties:
        answerId:
          type: integer
          format: int32
        checklistId:
          type: integer
          format: int32
        questionText:
          type: string
          nullable: true
        questionAnswer:
          type: string
          nullable: true
        comments:
          type: string
          nullable: true
        questionOrder:
          type: integer
          format: int32
      additionalProperties: false
  securitySchemes:
    ApiClientCredentials:
      type: http
      description: >-
        Swagger / Postman only: **Client ID** as username, **Client secret** as
        password. In Postman, set this once on the **collection** (Authorization
        → Basic Auth) so all requests inherit. For production server-to-server
        code, prefer **`X-OM-Auth-ID`** and **`X-OM-Auth-Key`** headers.
      scheme: basic

````