> ## 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 entity by key

> Returns full detail for one client entity, including contact fields, addresses where configured, custom field values, and identity verification summary when present.

**`customFields`** — populated custom field values for the client (active field definitions only). Each item includes `customFieldId`, `name`, `type`, stored `value`, and `displayValue` (human-readable; e.g. checkbox Yes/No, user list names, dates as `yyyy-MM-dd`).

**`verification`** — requested verification method (from linked onboarding client when applicable), verification outcome, status, integration check IDs, and document reference fields.

**404:** Unknown key or entity not in 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/entities/{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/entities/{key}:
    get:
      tags:
        - Entities
      summary: Get entity by key
      description: "Returns full detail for one client entity, including contact fields, addresses where configured, custom field values, and identity verification summary when present.\r\n\r\n**`customFields`** — populated custom field values for the client (active field definitions only). Each item includes `customFieldId`, `name`, `type`, stored `value`, and `displayValue` (human-readable; e.g. checkbox Yes/No, user list names, dates as `yyyy-MM-dd`).\r\n\r\n**`verification`** — requested verification method (from linked onboarding client when applicable), verification outcome, status, integration check IDs, and document reference fields.\r\n\r\n**404:** Unknown key or entity not in your practice.\r\n\r\n**429:** Rate limit exceeded."
      parameters:
        - name: key
          in: path
          description: Client entity key (identifier).
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Entity detail including custom fields when set
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/Application.APIData.DataObjects.EntityDetailDTO
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails'
        '500':
          description: Internal Server Error
components:
  schemas:
    Application.APIData.DataObjects.EntityDetailDTO:
      type: object
      properties:
        practiceKey:
          type: string
          nullable: true
        entityKey:
          type: string
          format: uuid
          nullable: true
        externalSystemID:
          type: string
          nullable: true
        entityCode:
          type: string
          nullable: true
        entityName:
          type: string
          nullable: true
        otherName:
          type: string
          nullable: true
        entitySurname:
          type: string
          nullable: true
        fullName:
          type: string
          nullable: true
        entitySalutation:
          type: string
          description: >-
            Friendly or preferred name for the client (not an honorific title
            such as Mr or Ms).
          nullable: true
        entityInitials:
          type: string
          nullable: true
        birthDate:
          type: string
          format: date
          nullable: true
        incorporationDate:
          type: string
          format: date
          nullable: true
        birthPlace:
          type: string
          nullable: true
        gender:
          type: string
          nullable: true
        email:
          type: string
          nullable: true
        telephone:
          type: string
          nullable: true
        mobile:
          type: string
          nullable: true
        regNumber:
          type: string
          nullable: true
        salesTaxNumber:
          type: string
          nullable: true
        taxNotRequired:
          type: boolean
        entityTerminated:
          type: boolean
        terminatedDate:
          type: string
          format: date-time
          nullable: true
        isTaxEntity:
          type: boolean
        isAMLEntity:
          type: boolean
        isSecEntity:
          type: boolean
        note:
          type: string
          nullable: true
        createdOn:
          type: string
          format: date-time
          nullable: true
        updatedOn:
          type: string
          format: date-time
          nullable: true
        entityTypeName:
          type: string
          nullable: true
        clientStatusName:
          type: string
          nullable: true
        partnerName:
          type: string
          nullable: true
        partnerKey:
          type: string
          nullable: true
        managerName:
          type: string
          nullable: true
        managerKey:
          type: string
          nullable: true
        inChargeName:
          type: string
          nullable: true
        inChargeKey:
          type: string
          nullable: true
        officeName:
          type: string
          nullable: true
        groupName:
          type: string
          nullable: true
        addresses:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.EntityAddressDTO
          nullable: true
        customFields:
          type: array
          items:
            $ref: >-
              #/components/schemas/Application.APIData.DataObjects.EntityCustomFieldApiDTO
          description: >-
            Custom field values set on this client (active definitions only).
            Empty array when none are set.
        verification:
          $ref: >-
            #/components/schemas/Application.APIData.DataObjects.EntityVerificationApiDTO
      additionalProperties: false
      example:
        practiceKey: 7e8f9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b
        entityKey: 2c4f6a88-1b3d-5e7f-90ab-cdef12345678
        externalSystemID: CRM-88421
        entityCode: RS-10492
        entityName: Riverstone Holdings Ltd
        fullName: Riverstone Holdings Ltd
        entitySalutation: Riverstone
        birthDate: '1990-05-15'
        email: accounts@riverstone.example
        telephone: +61 3 9000 1200
        entityTypeName: Company
        clientStatusName: Active
        taxNotRequired: false
        entityTerminated: false
        isTaxEntity: true
        updatedOn: '2025-04-10T04:05:00Z'
        verification:
          requestedMethod: ComplyCube
          isVerified: true
          verifiedDate: '2025-04-09T12:00:00Z'
          verificationMethod: ComplyCube
          verificationStatus: complete
          documentCheckId: chk_doc_abc123
          identityCheckId: chk_id_xyz789
          amlCheckId: chk_aml_def456
        customFields:
          - customFieldId: 42
            name: Industry sector
            type: Drop-Down
            value: Professional services
            displayValue: Professional services
            updatedOn: '2025-04-10T04:05:00Z'
          - customFieldId: 7
            name: Partner responsible
            type: User List
            value: '123'
            displayValue: Jane Smith
            updatedOn: '2025-03-01T10: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.APIData.DataObjects.EntityAddressDTO:
      type: object
      properties:
        addressType:
          type: string
          nullable: true
        address1:
          type: string
          nullable: true
        address2:
          type: string
          nullable: true
        address3:
          type: string
          nullable: true
        address4:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        postcode:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
        fullAddress:
          type: string
          nullable: true
      additionalProperties: false
    Application.APIData.DataObjects.EntityCustomFieldApiDTO:
      type: object
      properties:
        customFieldId:
          type: integer
          description: Practice custom field definition id.
          format: int64
        name:
          type: string
          description: Display name of the field.
        type:
          type: string
          description: Field type (e.g. Text, Drop-Down, Checkbox, User List, Date).
        value:
          type: string
          description: Stored value.
          nullable: true
        displayValue:
          type: string
          description: Human-readable value.
          nullable: true
        updatedOn:
          type: string
          description: Last update (UTC).
          format: date-time
          nullable: true
      additionalProperties: false
      example:
        customFieldId: 42
        name: Industry sector
        type: Drop-Down
        value: Professional services
        displayValue: Professional services
        updatedOn: '2025-04-10T04:05:00Z'
    Application.APIData.DataObjects.EntityVerificationApiDTO:
      type: object
      properties:
        requestedMethod:
          type: string
          nullable: true
        isVerified:
          type: boolean
        verifiedDate:
          type: string
          format: date-time
          nullable: true
        verificationMethod:
          type: string
          nullable: true
        verificationStatus:
          type: string
          nullable: true
        externalId:
          type: string
          nullable: true
        documentCheckId:
          type: string
          nullable: true
        identityCheckId:
          type: string
          nullable: true
        amlCheckId:
          type: string
          nullable: true
        multiBureauCheckId:
          type: string
          nullable: true
        primaryDocument:
          type: string
          nullable: true
        primaryDocumentBack:
          type: string
          nullable: true
        secondaryDocument:
          type: string
          nullable: true
        thirdDocument:
          type: string
          nullable: true
      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

````