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

# List customers

> List individual customers in your organisation. Use this as a
polling source — pass `updated_since` so each poll only returns
records that changed since the previous run.

Pagination is cursor-based: pass the `next_cursor` value from the
previous response as `cursor` on the next call.


List individual customers in your organisation. This is the primary
polling source for syncing status into your CRM.

## Polling pattern

Pass `updated_since` set to the timestamp of your last poll. Each call
then returns only customers updated since then:

```http theme={null}
GET /v1/customers?updated_since=2026-06-23T00:00:00Z&limit=100
```

Walk pages with the `cursor` field. See
[Polling for status](/guides/polling-status) for a robust loop, and
[Pagination](/concepts/pagination) for the cursor mechanics.

## Filtering

| Query parameter | Effect                                                |
| --------------- | ----------------------------------------------------- |
| `status`        | KYC status (e.g. `IN_PROGRESS`, `VERIFIED`).          |
| `aml_status`    | AML compliance status (e.g. `NEEDS_REVIEW`, `CLEAR`). |
| `updated_since` | ISO-8601 timestamp lower bound.                       |
| `external_id`   | Lookup by your CRM identifier.                        |
| `limit`         | 1–100. Default 50.                                    |
| `cursor`        | Continuation cursor from the previous response.       |

## Returned shape

Only individual customer types (`INDIVIDUAL`, `SOLE_TRADER`) are
returned. Entity customers (companies, trusts, partnerships, SMSFs)
live on their own list — see
[`GET /entities`](/api-reference/entities/list).


## OpenAPI

````yaml GET /customers
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:
  /customers:
    get:
      tags:
        - Customers
      summary: List customers
      description: |
        List individual customers in your organisation. Use this as a
        polling source — pass `updated_since` so each poll only returns
        records that changed since the previous run.

        Pagination is cursor-based: pass the `next_cursor` value from the
        previous response as `cursor` on the next call.
      operationId: listCustomers
      parameters:
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
          description: Number of records to return (1–100).
        - in: query
          name: cursor
          schema:
            type: string
          description: Opaque cursor from the previous response's `next_cursor`.
        - in: query
          name: status
          schema:
            $ref: '#/components/schemas/KycStatus'
          description: Filter by KYC status.
        - in: query
          name: aml_status
          schema:
            $ref: '#/components/schemas/AmlStatus'
          description: Filter by AML compliance status.
        - in: query
          name: updated_since
          schema:
            type: string
            format: date-time
          description: ISO-8601 timestamp. Return only customers updated after this time.
        - in: query
          name: external_id
          schema:
            type: string
          description: Lookup by your CRM identifier.
        - in: query
          name: include
          schema:
            type: string
            enum:
              - total_count
          description: |
            Comma-separated list of opt-in response fields. Currently the
            only supported value is `total_count`, which adds an exact
            count of the **filtered** set to the response envelope. Costs
            an extra `COUNT(*)` query — omit it on hot polling loops.
      responses:
        '200':
          description: Paginated customer list.
          content:
            application/json:
              schema:
                type: object
                required:
                  - object
                  - data
                  - has_more
                  - next_cursor
                  - limit
                properties:
                  object:
                    type: string
                    enum:
                      - list
                    description: Always `"list"` for paginated envelopes.
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Customer'
                  has_more:
                    type: boolean
                    description: >-
                      True if at least one more page exists. Use as the loop
                      condition.
                  next_cursor:
                    type: string
                    nullable: true
                    description: >-
                      Pass as `cursor` on the next request, or `null` when no
                      more pages.
                  limit:
                    type: integer
                    description: >-
                      The limit echoed back after defaulting/clamping (1–100,
                      default 50).
                  total_count:
                    type: integer
                    description: >
                      Total records matching the filter set (not the page). Only
                      present

                      when the request included `include=total_count`.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/ForbiddenScope'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  schemas:
    KycStatus:
      type: string
      enum:
        - NOT_STARTED
        - PENDING
        - IN_PROGRESS
        - VERIFIED
        - FAILED
        - NOT_REQUIRED
        - AWAITING_RESUBMISSION
    AmlStatus:
      type: string
      enum:
        - NOT_SCREENED
        - IN_PROGRESS
        - CLEAR
        - NEEDS_REVIEW
        - RESOLVED
    Customer:
      type: object
      required:
        - id
        - type
        - full_name
        - kyc_status
        - aml
        - added_via
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Instant Compliance customer UUID.
        external_id:
          type: string
          nullable: true
        type:
          $ref: '#/components/schemas/CustomerType'
        full_name:
          type: string
        email:
          type: string
          format: email
          nullable: true
        kyc_status:
          $ref: '#/components/schemas/KycStatus'
        kyc_started_at:
          type: string
          format: date-time
          nullable: true
        kyc_completed_at:
          type: string
          format: date-time
          nullable: true
        identity:
          $ref: '#/components/schemas/Identity'
        aml:
          $ref: '#/components/schemas/AmlBlock'
        added_via:
          $ref: '#/components/schemas/AddedVia'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      example:
        id: 550e8400-e29b-41d4-a716-446655440000
        external_id: crm-7741
        type: INDIVIDUAL
        full_name: Jane Doe
        email: jane@example.com
        kyc_status: VERIFIED
        kyc_started_at: '2026-06-23T01:00:00Z'
        kyc_completed_at: '2026-06-23T01:12:00Z'
        identity:
          verified_legal_name: JANE DOE
          verified_country: AUS
        aml:
          status: CLEAR
          screened_at: '2026-06-23T01:12:00Z'
          last_reviewed_at: null
          flags:
            pep: false
            sanctions: false
            adverse_media: false
            terrorism: false
        added_via: INTEGRATION
        created_at: '2026-06-22T22:14:00Z'
        updated_at: '2026-06-23T01:12:05Z'
    CustomerType:
      type: string
      enum:
        - INDIVIDUAL
        - SOLE_TRADER
      description: |
        Individual customer types — `/customers` only ingests these.
        Entity customers (companies, trusts, partnerships, SMSFs) live on
        `/entities` with their own `EntityType`.
    Identity:
      type: object
      nullable: true
      description: |
        Populated only when `kyc_status = VERIFIED`. Deliberately minimal —
        full date of birth and full address are never exposed.
      properties:
        verified_legal_name:
          type: string
          nullable: true
          description: Legal name extracted from the verified ID document.
        verified_country:
          type: string
          nullable: true
          description: ISO 3166-1 alpha-3 country code.
    AmlBlock:
      type: object
      required:
        - status
        - flags
      properties:
        status:
          $ref: '#/components/schemas/AmlStatus'
        screened_at:
          type: string
          format: date-time
          nullable: true
        last_reviewed_at:
          type: string
          format: date-time
          nullable: true
        flags:
          type: object
          required:
            - pep
            - sanctions
            - adverse_media
            - terrorism
          properties:
            pep:
              type: boolean
            sanctions:
              type: boolean
            adverse_media:
              type: boolean
            terrorism:
              type: boolean
    AddedVia:
      type: string
      description: How the record entered Instant Compliance.
      enum:
        - ADMIN_MANUAL
        - AI_EXTRACTED
        - CONTACT_PORTAL
        - BULK_IMPORT
        - INTEGRATION
        - SYSTEM
    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
  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.
    ForbiddenScope:
      description: API key lacks the required scope.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: forbidden_scope
              message: This API key does not have the required scope. customers:write
              details:
                required_scope: customers:write
    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_…`.

````