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

# Create a group

> Create a group — a multi-party deal/matter workspace. For real
estate and buyer's agents this is typically **one group per
property**: pass the property address as `name` and your CRM's
listing/deal id as `reference`, and call this endpoint from your
CRM's "property created" webhook.

Provide **either** a `templateId` (see `GET /group-templates`) —
the template's roles become the group's party slots and any
folded-in workflow is started — **or** explicit `parties`, each
optionally pre-attached to a customer by Instant Compliance id
(`customerId`) or by your own id (`customerExternalId`, as
supplied on `POST /customers`). Not both.

### Duplicate guard

* If `reference` is supplied and an **active group with the same
  reference** already exists in your organisation, that group is
  returned with **200 OK** and nothing is created — webhook
  retries and re-syncs are safe by construction.
* Otherwise the group is created and returned with **201 Created**.

Include an `Idempotency-Key` header to also make network retries
safe for 24 hours.

Requires the `groups:write` scope and the Groups feature enabled
for your organisation (`403 feature_disabled` otherwise).


Create a **group** — a multi-party deal/matter workspace that bundles
the customers involved in one transaction. For real estate and buyer's
agents this is typically **one group per property**: wire your CRM's
"property created" webhook to this endpoint, passing the property
address as `name` and your listing/deal id as `reference`.

## Template or explicit parties

Provide **either**:

* `templateId` — the template's roles become the group's party slots
  and any folded-in workflow is started. Discover ids with
  [List group templates](/api-reference/groups/list-templates).
* `parties` — explicit role slots, each optionally pre-attached to a
  customer by Instant Compliance UUID (`customerId`) or by your own id
  (`customerExternalId`, as supplied on `POST /customers`).

Not both — a template defines its own slots. When creating from a
template, attach customers afterwards in-app (or create the customers
first via `POST /customers` and use explicit parties instead).

## Duplicate guard

When `reference` is supplied and an **active group with the same
reference** already exists, that group is returned with `200 OK` and
nothing is created. This makes CRM webhook retries and full re-syncs
safe by construction. New groups return `201 Created`.

For transport-level retry safety you can additionally send an
`Idempotency-Key` header (24-hour replay window).

## Requirements

* Scope: `groups:write`
* The **Groups feature** must be enabled for your organisation —
  otherwise the request fails with `403 feature_disabled`.

## After creation

The response's `url` deep-links to the group workspace in the Instant
Compliance app, where your compliance team sees the parties, requests
documents, and runs verification. Nothing is charged and no
verification is triggered by this call.


## OpenAPI

````yaml POST /groups
openapi: 3.1.0
info:
  title: Instant Compliance API
  version: 1.0.0
  summary: External integration API for Instant Compliance.
  description: |
    The Instant Compliance v1 API lets your systems push customers into
    Instant Compliance and pull their verification / AML status back out.
    Designed for server-to-server use (CRMs, Zapier, internal back-office
    tools).

    **Base URL:** `https://app.instantcompliance.ai/api/v1`

    **Authentication:** Bearer API key — `Authorization: Bearer ic_live_…`
    Issue keys from **Settings → Developers** in your Instant Compliance
    organisation.

    **Scope:** individual customers (`INDIVIDUAL` and `SOLE_TRADER`, KYC)
    live on `/customers`; entity customers (companies, trusts,
    partnerships, SMSFs — KYB) live on `/entities`.
  contact:
    name: Instant Compliance Support
    email: support@instantcompliance.ai
    url: https://instantcompliance.ai
  license:
    name: Proprietary
servers:
  - url: https://app.instantcompliance.ai/api/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Customers
    description: |
      Create, read, and update individual customer records ingested through
      the external API.
  - name: Entities
    description: |
      Create, read, and update entity customer records (companies, trusts,
      partnerships, SMSFs). Entities verify via KYB instead of KYC; the API
      ingests the record and reports status — verification is started by
      your back-office team in-app.
  - name: Designated services
    description: |
      Read-only catalog of the designated-service codes accepted when
      creating customers.
  - name: Groups
    description: |
      Create group workspaces (multi-party deals/matters — e.g. one per
      property for real-estate integrators) and discover the group
      templates available to your organisation. Requires the Groups
      feature to be enabled for your organisation.
paths:
  /groups:
    post:
      tags:
        - Groups
      summary: Create a group
      description: |
        Create a group — a multi-party deal/matter workspace. For real
        estate and buyer's agents this is typically **one group per
        property**: pass the property address as `name` and your CRM's
        listing/deal id as `reference`, and call this endpoint from your
        CRM's "property created" webhook.

        Provide **either** a `templateId` (see `GET /group-templates`) —
        the template's roles become the group's party slots and any
        folded-in workflow is started — **or** explicit `parties`, each
        optionally pre-attached to a customer by Instant Compliance id
        (`customerId`) or by your own id (`customerExternalId`, as
        supplied on `POST /customers`). Not both.

        ### Duplicate guard

        * If `reference` is supplied and an **active group with the same
          reference** already exists in your organisation, that group is
          returned with **200 OK** and nothing is created — webhook
          retries and re-syncs are safe by construction.
        * Otherwise the group is created and returned with **201 Created**.

        Include an `Idempotency-Key` header to also make network retries
        safe for 24 hours.

        Requires the `groups:write` scope and the Groups feature enabled
        for your organisation (`403 feature_disabled` otherwise).
      operationId: createGroup
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateGroupRequest'
            examples:
              fromTemplate:
                summary: From a template (recommended)
                value:
                  name: 12 Smith St, Richmond VIC 3121
                  reference: crm-listing-8841
                  templateId: 550e8400-e29b-41d4-a716-446655440000
              explicitParties:
                summary: With explicit party slots
                value:
                  name: 12 Smith St, Richmond VIC 3121
                  reference: crm-listing-8841
                  parties:
                    - roleLabel: Vendor
                      partyType: EITHER
                    - roleLabel: Purchaser
                      partyType: EITHER
                      customerExternalId: crm-7741
      responses:
        '200':
          description: >-
            An active group with this `reference` already exists — returned
            unchanged.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
        '201':
          description: New group created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/FeatureDisabledOrScope'
        '404':
          description: The supplied `templateId` does not exist in this organisation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: not_found
                  message: Group template not found.
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '429':
          $ref: '#/components/responses/RateLimited'
      x-codeSamples:
        - lang: curl
          source: |
            curl -X POST https://app.instantcompliance.ai/api/v1/groups \
              -H "Authorization: Bearer ic_live_..." \
              -H "Content-Type: application/json" \
              -H "Idempotency-Key: crm-listing-8841-created" \
              -d '{
                "name": "12 Smith St, Richmond VIC 3121",
                "reference": "crm-listing-8841",
                "templateId": "550e8400-e29b-41d4-a716-446655440000"
              }'
components:
  parameters:
    IdempotencyKey:
      in: header
      name: Idempotency-Key
      required: false
      schema:
        type: string
        maxLength: 255
      description: |
        Caller-supplied unique key for safe retries. Repeat the same key
        within 24 hours and we replay the original response instead of
        repeating the side effect. Reusing the key with a *different*
        request body returns **409 idempotency_conflict**.
  schemas:
    CreateGroupRequest:
      type: object
      required:
        - name
      additionalProperties: false
      properties:
        name:
          type: string
          maxLength: 255
          description: Display name — e.g. the property address.
        reference:
          type: string
          maxLength: 255
          description: |
            Your stable deal/listing id. Also the duplicate guard — an
            existing active group with the same reference is returned
            instead of creating a twin.
        templateId:
          type: string
          format: uuid
          description: |
            Group template to instantiate (see `GET /group-templates`).
            Mutually exclusive with `parties`.
        parties:
          type: array
          maxItems: 50
          items:
            $ref: '#/components/schemas/GroupPartyInput'
    Group:
      type: object
      required:
        - id
        - name
        - reference
        - status
        - template_id
        - parties
        - url
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        reference:
          type: string
          nullable: true
        status:
          type: string
          enum:
            - ACTIVE
            - ON_HOLD
            - COMPLETE
            - ARCHIVED
        template_id:
          type: string
          format: uuid
          nullable: true
        industry:
          type: string
          nullable: true
        parties:
          type: array
          items:
            $ref: '#/components/schemas/GroupParty'
        url:
          type: string
          format: uri
          description: Deep link to the group workspace in the Instant Compliance app.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      example:
        id: 7f6f2c1a-4a3d-4f5e-9b3c-2f1f0a9d8e7c
        name: 12 Smith St, Richmond VIC 3121
        reference: crm-listing-8841
        status: ACTIVE
        template_id: 550e8400-e29b-41d4-a716-446655440000
        industry: REAL_ESTATE
        parties:
          - id: 1c9a7e42-11f3-4f0c-8a4e-6a2f9b8d7c6e
            role_label: Vendor
            party_type: EITHER
            required: true
            customer_id: null
          - id: 3e8b6d21-9c4f-4a1d-b7e2-5f0a8c9d1b2a
            role_label: Purchaser
            party_type: EITHER
            required: true
            customer_id: 9d8c7b6a-5e4f-4d3c-2b1a-0f9e8d7c6b5a
        url: >-
          https://app.instantcompliance.ai/groups/7f6f2c1a-4a3d-4f5e-9b3c-2f1f0a9d8e7c
        created_at: '2026-07-20T03:20:00Z'
        updated_at: '2026-07-20T03:20:00Z'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - forbidden_scope
                - not_found
                - validation_failed
                - conflict
                - insufficient_credits
                - rate_limited
                - idempotency_conflict
                - feature_disabled
                - internal
            message:
              type: string
            details:
              type: object
              additionalProperties: true
    GroupPartyInput:
      type: object
      required:
        - roleLabel
      additionalProperties: false
      properties:
        roleLabel:
          type: string
          maxLength: 120
          description: The role this slot represents — e.g. `Vendor`, `Purchaser`.
        partyType:
          $ref: '#/components/schemas/GroupPartyType'
        required:
          type: boolean
          default: true
        customerId:
          type: string
          format: uuid
          description: Instant Compliance customer id to attach to this slot.
        customerExternalId:
          type: string
          maxLength: 255
          description: |
            Your own id for the customer (as supplied on
            `POST /customers`). Mutually exclusive with `customerId`.
    GroupParty:
      type: object
      required:
        - id
        - role_label
        - party_type
        - required
        - customer_id
      properties:
        id:
          type: string
          format: uuid
        role_label:
          type: string
        party_type:
          $ref: '#/components/schemas/GroupPartyType'
        required:
          type: boolean
        customer_id:
          type: string
          format: uuid
          nullable: true
    GroupPartyType:
      type: string
      enum:
        - INDIVIDUAL
        - ENTITY
        - EITHER
      description: |
        What kind of customer may fill a party slot. `EITHER` accepts an
        individual or an entity.
  responses:
    Unauthorized:
      description: Missing, invalid, expired, or revoked API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
              message: Invalid or revoked API key.
    FeatureDisabledOrScope:
      description: |
        API key lacks the required scope, or the Groups feature is not
        enabled for the organisation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: feature_disabled
              message: >-
                The Groups feature is not enabled for this organisation. Contact
                support to enable it.
              details:
                feature: Groups
    ValidationFailed:
      description: Request payload failed schema validation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: validation_failed
              message: Invalid customer payload.
              details:
                issues:
                  email:
                    - Must be a valid email address.
    RateLimited:
      description: Burst or daily rate limit exceeded for this API key.
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds to wait before retrying.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limited
              message: Rate limit exceeded. Slow down and retry shortly.
              details:
                limit: 60
                window_seconds: 60
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: |
        Bearer API key issued from **Settings → Developers** in your
        Instant Compliance organisation. Format: `ic_live_…`.

````