> ## 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.

# Replace a proposal

> Replace every section of a proposal. Anything you leave out is removed.

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 PUT /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. Edit an existing proposal's services with **`PATCH /api/v1/proposals/{key}/services`** (line edits) or **`PUT /api/v1/proposals/{key}/services`** (replace the list).**`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**Payments** — **`GET /api/v1/payments/list`** lists payments by payment-date range, filterable by `paymentStatus` (`processing`, `completed`, `refunded`, `failed`), `paymentMethod` (`card`, `bank`, `external`, `xero`, `quickbooks`) and `entityKey`. **`GET /api/v1/payments/{paymentId}`** loads one payment (including refund details); **`GET /api/v1/bills/{billingId}/payments`** lists every payment against a bill. Saved payment sources (card or bank account details) are never returned.\r\n\r\n**Debtors** — **`GET /api/v1/debtors/ageing`** returns outstanding receivables as at a date (practice totals plus per-client buckets: current, 1–30, 31–60, 61–90, 90+ days overdue). **`GET /api/v1/debtors/invoices`** lists outstanding invoices with days overdue, collection status and payment-plan flags. **`GET /api/v1/debtors/movement`** reconciles opening → billed → paid → closing balance over a period.\r\n\r\n**Statements** — **`GET /api/v1/statements/list?entityKey=`** lists statements sent to a client; **`GET /api/v1/statements/{statementId}`** returns the statement with its lines; **`GET /api/v1/statements/{statementId}/pdf`** downloads the statement PDF.\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}:
    put:
      tags:
        - Proposal updates
      summary: Replace a proposal
      description: "Replaces the whole proposal with the body you send — the same body as **POST `/api/v1/proposals`** (without `entityKey` changes or `sendToClient`). **Every section is replaced: anything you do not send is removed** (jobs, invoices, eForm, checklist, documents…). Signatories are only replaced when you send them.\r\n\r\nItems with **`id`** keep that item (services, invoices, recurring billings, jobs); use this to keep items already pushed to another system.\r\n\r\nRuns the step updates in order (services, details, signatories, billing, XPM, FYI, Karbon, GreatSoft, FreeAgent, eForm, checklist). It is not one transaction: if a step fails, the error names it and earlier steps stay saved.\r\n\r\nOnboarding, identity verification and ethical letters cannot be changed through the API yet.\r\n**Rules for every update route**\r\n\r\n- **`userKey`** — staff member making the change (**GET `/api/v1/users/list`**).\r\n- Field names, lookups and validation are the same as **POST `/api/v1/proposals`**.\r\n- Accepted, completed, due-for-renewal and renewed proposals cannot be edited.\r\n- Editing a proposal that has already been sent changes what the client sees.\r\n- Items already pushed to another system (XPM, FYI, Karbon, GreatSoft, FreeAgent), signed signatories, and invoices that are synced, paid or cancelled cannot be changed or removed. In a PUT, include them as `{ \"id\": … }` to keep them.\r\n- **Response**: `pricing` (services, invoices, recurring billing, jobs) and `section` (this step as saved, with ids).\r\n\r\nWrite access is required. **429** — rate limit exceeded."
      parameters:
        - name: key
          in: path
          description: Proposal key.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/Application.APIData.DataObjects.ProposalCreateRequestDTO
          text/json:
            schema:
              $ref: >-
                #/components/schemas/Application.APIData.DataObjects.ProposalCreateRequestDTO
          application/*+json:
            schema:
              $ref: >-
                #/components/schemas/Application.APIData.DataObjects.ProposalCreateRequestDTO
      responses:
        '200':
          description: OK
          content:
            text/plain:
              schema:
                $ref: >-
                  #/components/schemas/Application.APIData.DataObjects.ProposalUpdateResponseDTO
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/Application.APIData.DataObjects.ProposalUpdateResponseDTO
            text/json:
              schema:
                $ref: >-
                  #/components/schemas/Application.APIData.DataObjects.ProposalUpdateResponseDTO
        '400':
          description: Bad Request
          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'
        '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'
        '403':
          description: Forbidden
          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'
components:
  schemas:
    Application.APIData.DataObjects.ProposalCreateRequestDTO:
      type: object
      properties:
        userKey:
          type: string
          format: uuid
        entityKey:
          type: string
          format: uuid
        sendToClient:
          type: boolean
        name:
          type: string
          nullable: true
        note:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
          nullable: true
        endDate:
          type: string
          format: date-time
          nullable: true
        startOnAcceptance:
          type: boolean
          nullable: true
        currencyID:
          type: integer
          format: int32
          nullable: true
        lengthID:
          type: integer
          format: int32
          nullable: true
        terms:
          type: integer
          format: int32
          nullable: true
        refNo:
          type: string
          nullable: true
        services:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateServiceDTO
          nullable: true
        xpmJobs:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateXpmJobDTO
          nullable: true
        fyiJobs:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateFyiJobDTO
          nullable: true
        invoices:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateInvoiceDTO
          nullable: true
        recurringBillings:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateRecurringBillingDTO
          nullable: true
        requestPaymentDetails:
          type: boolean
        paymentDetailsType:
          type: integer
          format: int32
          nullable: true
        sendSms:
          type: boolean
          nullable: true
        expiryDate:
          type: string
          format: date-time
          nullable: true
        identityVerification:
          type: boolean
        verificationMethod:
          type: string
          nullable: true
        identityPeople:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateIdentityPersonDTO
          nullable: true
        onboarding:
          $ref: >-
            #/components/schemas/Application.APIData.DataObjects.ProposalCreateOnboardingDTO
        businessSignatoryUserKey:
          type: string
          format: uuid
          nullable: true
        requiresApproval:
          type: boolean
          nullable: true
        approverUserKey:
          type: string
          format: uuid
          nullable: true
        termsDetailsOverride:
          type: string
          nullable: true
        stpID:
          type: integer
          format: int32
          nullable: true
        stpDetailsOverride:
          type: string
          nullable: true
        documents:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateDocumentDTO
          nullable: true
        attachmentID:
          type: integer
          format: int32
          nullable: true
        coverPageID:
          type: integer
          format: int32
          nullable: true
        welcomeMessageID:
          type: integer
          format: int32
          nullable: true
        emailSubject:
          type: string
          nullable: true
        emailContent:
          type: string
          nullable: true
        packages:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreatePackageDTO
          nullable: true
        popularPackage:
          type: integer
          format: int32
          nullable: true
        showServiceMenu:
          type: boolean
          nullable: true
        serviceGrouping:
          type: integer
          format: int32
          nullable: true
        signatories:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateSignatoryDTO
          nullable: true
        includeCdd:
          type: boolean
          nullable: true
        payerID:
          type: string
          nullable: true
        billFromServices:
          $ref: >-
            #/components/schemas/Application.APIData.DataObjects.ProposalCreateBillFromServicesDTO
        formTemplateID:
          type: integer
          format: int32
          nullable: true
        ethicalLetter:
          $ref: >-
            #/components/schemas/Application.APIData.DataObjects.ProposalCreateEthicalLetterDTO
        checklist:
          $ref: >-
            #/components/schemas/Application.APIData.DataObjects.ProposalCreateChecklistDTO
        karbonWorkItems:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateKarbonWorkItemDTO
          nullable: true
        greatSoftTasks:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateGreatSoftTaskDTO
          nullable: true
        freeAgentProjects:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateFreeAgentProjectDTO
          nullable: true
      additionalProperties: false
      example:
        userKey: 11111111-2222-3333-4444-555555555555
        entityKey: 2c4f6a88-1b3d-5e7f-90ab-cdef12345678
        name: FY26 tax engagement
        sendToClient: false
        startOnAcceptance: true
        note: Adhoc proposal with custom services and jobs.
        services:
          - serviceID: 12040
            quantity: 1
            packageNumber: 1
        xpmJobs:
          - name: Income tax return
            templateUuid: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
        fyiJobs:
          - jobName: Income tax return
            fyiTemplateId: '10492'
            state: Planned
            managerEmail: manager@practice.example
            partnerEmail: partner@practice.example
        invoices:
          - billDate: '2026-07-01'
            dueDate: '2026-07-31'
            billNow: 1
            lineItems:
              - amount: 2450
                taxPercent: 10
                narration: Annual tax return
                serviceID: 12040
        requestPaymentDetails: true
        paymentDetailsType: 1
        terms: 42
        stpID: 7
        documents:
          - documentID: 15
        attachmentID: 3
        businessSignatoryUserKey: 11111111-2222-3333-4444-555555555555
        requiresApproval: true
        approverUserKey: 66666666-7777-8888-9999-000000000000
        packages:
          - packageNumber: 1
            name: Compliance
        emailSubject: Your FY26 engagement
        emailContent: '<p>Please review and accept: [Link]</p>'
        ethicalLetter:
          templateID: 4
          sendWhen: 89
          accountantName: Previous Accountant
          accountantEmail: accounts@previous.example
        checklist:
          templateID: 21
          signOffRequired: false
    Application.APIData.DataObjects.ProposalUpdateResponseDTO:
      type: object
      properties:
        engagementKey:
          type: string
          format: uuid
        statusName:
          type: string
          nullable: true
        billingNeedsReview:
          type: boolean
        pricing:
          $ref: >-
            #/components/schemas/Application.APIData.DataObjects.ProposalPricingSnapshotDTO
        section:
          nullable: true
      additionalProperties: false
    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.APIData.DataObjects.ProposalCreateServiceDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
          nullable: true
        serviceID:
          type: integer
          format: int32
        quantity:
          type: number
          format: double
          nullable: true
        price:
          type: number
          format: double
          nullable: true
        taxAmount:
          type: number
          format: double
          nullable: true
        packageNumber:
          type: integer
          format: int32
          nullable: true
        isOptional:
          type: boolean
          nullable: true
        discountPerc:
          type: number
          format: double
          nullable: true
        discountAmount:
          type: number
          format: double
          nullable: true
        serviceDetail:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateXpmJobDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
          nullable: true
        remove:
          type: boolean
        name:
          type: string
          nullable: true
        templateUuid:
          type: string
          format: uuid
        categoryId:
          type: string
          format: uuid
          nullable: true
        description:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
          nullable: true
        dueDate:
          type: string
          format: date-time
          nullable: true
        refNo:
          type: string
          nullable: true
        budget:
          type: number
          format: double
          nullable: true
        partnerUuid:
          type: string
          format: uuid
          nullable: true
        managerUuid:
          type: string
          format: uuid
          nullable: true
        staffUuids:
          type: array
          items:
            type: string
            format: uuid
          nullable: true
        tasks:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalCreateXpmJobTaskDTO
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateFyiJobDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
          nullable: true
        remove:
          type: boolean
        jobName:
          type: string
          nullable: true
        fyiTemplateId:
          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
        sourceID:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateInvoiceDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
          nullable: true
        remove:
          type: boolean
        billDate:
          type: string
          format: date
        dueDate:
          type: string
          format: date
        billDetails:
          type: string
          nullable: true
        refNo:
          type: string
          nullable: true
        billNow:
          type: integer
          format: int32
          nullable: true
        syncNow:
          type: boolean
          nullable: true
        sendBill:
          type: boolean
          nullable: true
        brandingThemeID:
          type: string
          nullable: true
        packageNumber:
          type: integer
          format: int32
          nullable: true
        lineItems:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.BillCreateLineItemDTO
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateRecurringBillingDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
          nullable: true
        remove:
          type: boolean
        frequency:
          type: string
          nullable: true
        startDate:
          type: string
          format: date
        endDate:
          type: string
          format: date
          nullable: true
        nextRunDate:
          type: string
          format: date
          nullable: true
        dueDays:
          type: integer
          format: int32
          nullable: true
        billDetails:
          type: string
          nullable: true
        refNo:
          type: string
          nullable: true
        brandingThemeID:
          type: string
          nullable: true
        sendBill:
          type: boolean
          nullable: true
        billNow:
          type: integer
          format: int32
          nullable: true
        packageNumber:
          type: integer
          format: int32
          nullable: true
        lineItems:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.BillCreateLineItemDTO
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateIdentityPersonDTO:
      type: object
      properties:
        entityKey:
          type: string
          format: uuid
          nullable: true
        name:
          type: string
          nullable: true
        surname:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        mobile:
          type: string
          nullable: true
        verificationMethod:
          type: string
          nullable: true
        includeEngagement:
          type: boolean
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateOnboardingDTO:
      type: object
      properties:
        clients:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.OnboardingClientCreateDTO
          nullable: true
        recipients:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.OnboardingRecipientCreateDTO
          nullable: true
        groupID:
          type: integer
          format: int32
          nullable: true
        formTemplateID:
          type: integer
          format: int32
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateDocumentDTO:
      type: object
      properties:
        documentID:
          type: integer
          format: int64
        detailsOverride:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreatePackageDTO:
      type: object
      properties:
        packageNumber:
          type: integer
          format: int32
        name:
          type: string
          nullable: true
        price:
          type: number
          format: double
          nullable: true
        text:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateSignatoryDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
          nullable: true
        remove:
          type: boolean
        name:
          type: string
          nullable: true
        surname:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        mobile:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateBillFromServicesDTO:
      type: object
      properties:
        billNow:
          type: integer
          format: int32
          nullable: true
        packageNumber:
          type: integer
          format: int32
          nullable: true
        billDate:
          type: string
          format: date
          nullable: true
        dueDate:
          type: string
          format: date
          nullable: true
        sendBill:
          type: boolean
          nullable: true
        recurringSchedules:
          type: boolean
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateEthicalLetterDTO:
      type: object
      properties:
        templateID:
          type: integer
          format: int32
          nullable: true
        detail:
          type: string
          nullable: true
        sendWhen:
          type: integer
          format: int32
          nullable: true
        accountantName:
          type: string
          nullable: true
        accountantEmail:
          type: string
          nullable: true
        partnerUserKey:
          type: string
          format: uuid
          nullable: true
        requireDocuments:
          type: boolean
        documentRequirements:
          type: array
          items:
            type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateChecklistDTO:
      type: object
      properties:
        templateID:
          type: integer
          format: int32
        signOffRequired:
          type: boolean
        signOffUserKey:
          type: string
          format: uuid
          nullable: true
        notes:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateKarbonWorkItemDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
          nullable: true
        remove:
          type: boolean
        workTemplateKey:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        description:
          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
        primaryStatus:
          type: string
          nullable: true
        secondaryStatus:
          type: string
          nullable: true
        assigneeEmail:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateGreatSoftTaskDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
          nullable: true
        remove:
          type: boolean
        stdTaskID:
          type: integer
          format: int32
        officeCode:
          type: string
          nullable: true
        managerCode:
          type: string
          nullable: true
        partnerCode:
          type: string
          nullable: true
        billingManagerGuid:
          type: string
          nullable: true
        currencyCode:
          type: string
          nullable: true
        dateOpen:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalCreateFreeAgentProjectDTO:
      type: object
      properties:
        id:
          type: integer
          format: int64
          nullable: true
        remove:
          type: boolean
        name:
          type: string
          nullable: true
        budget:
          type: number
          format: double
          nullable: true
        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
          nullable: true
        includeUnbilledTimeInProfitability:
          type: boolean
          nullable: true
        startsOn:
          type: string
          format: date-time
          nullable: true
        endsOn:
          type: string
          format: date-time
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalPricingSnapshotDTO:
      type: object
      properties:
        engagementKey:
          type: string
          format: uuid
        name:
          type: string
          nullable: true
        statusID:
          type: integer
          format: int32
        statusName:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
        endDate:
          type: string
          format: date-time
          nullable: true
        currencyID:
          type: integer
          format: int32
        currencyName:
          type: string
          nullable: true
        createBills:
          type: boolean
        recurringBilling:
          type: integer
          format: int32
        createXpmJobs:
          type: boolean
        createFyiJobs:
          type: boolean
        servicesTotal:
          type: number
          format: double
        invoicesTotal:
          type: number
          format: double
        services:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalPricingServiceDTO
          nullable: true
        invoices:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalPricingInvoiceDTO
          nullable: true
        recurringBillings:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalPricingRecurringDTO
          nullable: true
        xpmJobs:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalPricingXpmJobDTO
          nullable: true
        fyiJobs:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalPricingFyiJobDTO
          nullable: true
      additionalProperties: false
      example:
        engagementKey: 8f9e2b1c-3d4a-5e6f-7890-abcdef012345
        name: FY25 tax engagement – Acme Pty Ltd
        statusName: Accepted
        createBills: true
        servicesTotal: 2695
        invoicesTotal: 2695
        services:
          - serviceID: 12040
            serviceName: Annual compliance — company
            price: 2450
            quantity: 1
            taxAmount: 245
            lineTotal: 2695
    Application.APIData.DataObjects.ProposalCreateXpmJobTaskDTO:
      type: object
      properties:
        taskID:
          type: integer
          format: int32
        label:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        startDate:
          type: string
          format: date-time
          nullable: true
        dueDate:
          type: string
          format: date-time
          nullable: true
        estimatedMinutes:
          type: integer
          format: int32
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.BillCreateLineItemDTO:
      type: object
      properties:
        amount:
          maximum: 99999999.99
          minimum: -99999999.99
          type: number
          format: double
        taxAmount:
          maximum: 99999999.99
          minimum: -99999999.99
          type: number
          format: double
          nullable: true
        taxPercent:
          maximum: 100
          minimum: 0
          type: number
          format: double
          nullable: true
        total:
          maximum: 99999999.99
          minimum: -99999999.99
          type: number
          format: double
          nullable: true
        narration:
          maxLength: 500
          type: string
          nullable: true
        extAccountID:
          type: integer
          format: int64
          nullable: true
        extItemID:
          type: integer
          format: int32
          nullable: true
        extTaxID:
          type: integer
          format: int32
          nullable: true
        orderID:
          type: integer
          format: int32
          nullable: true
        serviceID:
          type: integer
          format: int32
          nullable: true
        trackingOptionIDs:
          type: array
          items:
            type: string
          nullable: true
        greatSoftTaskCode:
          maxLength: 50
          type: string
          nullable: true
        greatSoftAllocationCode:
          maxLength: 50
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.OnboardingClientCreateDTO:
      type: object
      properties:
        entityKey:
          type: string
          format: uuid
          nullable: true
        clientCode:
          type: string
          nullable: true
        entityTypeId:
          type: integer
          format: int32
          nullable: true
        entityType:
          type: string
          nullable: true
        name:
          type: string
          nullable: true
        surname:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        mobile:
          type: string
          nullable: true
        requireTaxDetails:
          type: boolean
        identityVerification:
          type: boolean
        verificationMethod:
          type: string
          nullable: true
        requireDocuments:
          type: boolean
        documents:
          type: array
          items:
            type: string
          nullable: true
        requestAccountingFileAccess:
          type: boolean
        accountingFileInviteName:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.OnboardingRecipientCreateDTO:
      type: object
      properties:
        name:
          type: string
          nullable: true
        surname:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        mobile:
          type: string
          nullable: true
        sendSms:
          type: boolean
      additionalProperties: false
    Application.APIData.DataObjects.ProposalPricingServiceDTO:
      type: object
      properties:
        id:
          type: integer
          format: int32
        serviceID:
          type: integer
          format: int32
        parentServiceID:
          type: integer
          format: int32
          nullable: true
        serviceName:
          type: string
          nullable: true
        serviceDetail:
          type: string
          nullable: true
        price:
          type: number
          format: double
        quantity:
          type: number
          format: double
          nullable: true
        taxAmount:
          type: number
          format: double
        discountPerc:
          type: number
          format: double
        discountAmount:
          type: number
          format: double
        packageNumber:
          type: integer
          format: int32
        pricingTypeName:
          type: string
          nullable: true
        frequency:
          type: string
          nullable: true
        isOptional:
          type: boolean
        lineTotal:
          type: number
          format: double
      additionalProperties: false
    Application.APIData.DataObjects.ProposalPricingInvoiceDTO:
      type: object
      properties:
        billingID:
          type: integer
          format: int32
        billDate:
          type: string
          format: date
        dueDate:
          type: string
          format: date
        billDetails:
          type: string
          nullable: true
        refNo:
          type: string
          nullable: true
        billNow:
          type: integer
          format: int32
        syncNow:
          type: boolean
        sendBill:
          type: boolean
        billAmount:
          type: number
          format: double
        billTax:
          type: number
          format: double
        billTotal:
          type: number
          format: double
        packageNumber:
          type: integer
          format: int32
          nullable: true
        lineItems:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalPricingInvoiceLineDTO
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalPricingRecurringDTO:
      type: object
      properties:
        recurringBillingID:
          type: integer
          format: int64
        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
        refNo:
          type: string
          nullable: true
        dueDays:
          type: integer
          format: int32
        isActive:
          type: boolean
        billNow:
          type: integer
          format: int32
        lineItems:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.ProposalPricingInvoiceLineDTO
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalPricingXpmJobDTO:
      type: object
      properties:
        name:
          type: string
          nullable: true
        templateUuid:
          type: string
          format: uuid
          nullable: true
        categoryId:
          type: string
          format: uuid
          nullable: true
        startDate:
          type: string
          format: date-time
        dueDate:
          type: string
          format: date-time
        description:
          type: string
          nullable: true
        refNo:
          type: string
          nullable: true
        budget:
          type: number
          format: double
        partnerUuid:
          type: string
          format: uuid
          nullable: true
        managerUuid:
          type: string
          format: uuid
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalPricingFyiJobDTO:
      type: object
      properties:
        jobName:
          type: string
          nullable: true
        fyiTemplateId:
          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
        sourceID:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.ProposalPricingInvoiceLineDTO:
      type: object
      properties:
        amount:
          type: number
          format: double
        taxAmount:
          type: number
          format: double
        total:
          type: number
          format: double
        narration:
          type: string
          nullable: true
        extAccountID:
          type: integer
          format: int64
          nullable: true
        extItemID:
          type: integer
          format: int32
          nullable: true
        extTaxID:
          type: integer
          format: int32
          nullable: true
        serviceID:
          type: integer
          format: int32
          nullable: true
        orderID:
          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

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.