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

# Search contacts

> Search contacts by email, phone number, custom data, and more. Use when your application needs to find a contact without already holding its contact ID.

The `filter` is a list of `or` groups, each holding `and` rules. A contact matches when every rule in at least one group matches it.

```json theme={"dark"}
{
  "filter": {
    "or": [
      { "and": [{ "type": "contacts_email_in", "email_in": ["jane@open.cx"] }] },
      { "and": [{ "type": "contacts_phone_number_in", "phone_number_in": ["+966500000000"] }] },
      { "and": [{ "type": "contacts_attributes_in", "attributes": [{ "merchant_id": "12345" }] }] }
    ]
  }
}
```

## Matching rules

* `contacts_email_in` matches the full address and ignores letter case.
* `contacts_phone_number_in` compares digits only, so `+`, spaces, and dashes don't affect the match.
* In email and phone values, `*` turns the entry into a partial match: `*@open.cx` finds every address containing `@open.cx`.
* `contacts_attributes_in` matches custom data on an exact key and value. Each object in `attributes` is one alternative; a contact matches when it carries every key-value pair of any one object.

## Pagination

Each page returns up to 250 contacts. When more results exist, the response carries a `next` value; send it as `cursor` in the next request with the same `filter`. `next` is `null` on the last page.


## OpenAPI

````yaml post /contacts/search
openapi: 3.1.0
info:
  title: OpenCX API
  description: >

    OpenCX is an AI-powered, all-in-one platform for customer support and
    outbound communications.


    Use this API to manage your OpenCX organization's AI agents, actions,
    conversations, contacts, and more.


    To get started, generate a new API key from the dashboard.


    ## Authentication

    All API endpoints require authentication using a Bearer token. You can
    generate an API key from your OpenCX dashboard.


    ## Rate Limiting

    API requests are rate limited to ensure fair usage. The current limits are:

    - 100 requests per minute for standard endpoints

    - 1000 requests per minute for streaming endpoints


    ## Error Handling

    The API uses standard HTTP status codes and returns detailed error messages
    in the response body.
  version: 1.0-beta
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
  - url: http://localhost:8080
    description: Development
  - url: https://api.open.cx
    description: Production
security:
  - bearerAuth: []
paths:
  /contacts/search:
    post:
      summary: Search contacts
      description: >-
        Search contacts using composite filters (OR of AND groups). Each rule
        narrows the set; groups are combined with OR logic.
      operationId: searchContacts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchContactsInput'
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchContactsOutput'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorDto'
components:
  schemas:
    SearchContactsInput:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/SearchContactsInputInput'
      type: object
      properties:
        filter:
          $ref: '#/components/schemas/PublicContactsCompositeFilter'
        cursor:
          description: Pagination cursor to fetch the next set of results
          type: string
      required:
        - filter
    SearchContactsOutput:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/SearchContactsOutput'
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Contact'
        next:
          anyOf:
            - type: string
            - type: 'null'
      required:
        - items
        - next
      additionalProperties: false
    ErrorDto:
      type: object
      properties:
        statusCode:
          type: integer
        message:
          type: string
        error:
          type: string
    PublicContactsCompositeFilter:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/PublicContactsCompositeFilterInput'
      type: object
      properties:
        or:
          minItems: 1
          type: array
          items:
            type: object
            properties:
              and:
                type: array
                items:
                  $ref: '#/components/schemas/PublicContactsFilter'
            required:
              - and
      required:
        - or
    Contact:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/Contact'
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        primary_external_id:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The main account's external_id within your organization, or null
            when unlinked. The main contact may not exist yet. Set through
            external-ID widget authentication; contact create/update endpoints
            do not accept this field.
        email:
          anyOf:
            - type: string
              format: email
              pattern: >-
                ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
            - type: 'null'
        phone_number:
          anyOf:
            - type: string
            - type: 'null'
        name:
          anyOf:
            - type: string
            - type: 'null'
        custom_data:
          anyOf:
            - type: object
              propertyNames:
                type: string
              additionalProperties:
                type: string
            - type: 'null'
        non_verified_custom_data:
          anyOf:
            - type: object
              propertyNames:
                type: string
              additionalProperties:
                type: string
            - type: 'null'
          description: >-
            Custom data from unverified sources (e.g. an unauthenticated widget
            visitor), kept apart from custom_data
        created_at:
          type: string
          description: ISO 8601 timestamp of when the contact was created
        updated_at:
          type: string
          description: ISO 8601 timestamp of when the contact was last updated
      required:
        - id
        - primary_external_id
        - email
        - phone_number
        - name
        - custom_data
        - non_verified_custom_data
        - created_at
        - updated_at
      additionalProperties: false
    PublicContactsFilter:
      $schema: https://json-schema.org/draft/2020-12/schema
      $id: '#/components/schemas/PublicContactsFilterInput'
      anyOf:
        - type: object
          properties:
            type:
              type: string
              const: all_contacts
          required:
            - type
        - type: object
          properties:
            type:
              type: string
              const: contact_id_in
            contact_ids:
              type: array
              items:
                type: string
                format: uuid
                pattern: >-
                  ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          required:
            - type
            - contact_ids
        - type: object
          properties:
            type:
              type: string
              const: contacts_created_at_between
            after: {}
            before: {}
          required:
            - type
        - type: object
          properties:
            type:
              type: string
              const: contacts_email_domain_name_in
            domain_name_in:
              type: array
              items:
                type: string
          required:
            - type
            - domain_name_in
        - type: object
          properties:
            type:
              type: string
              const: contacts_name_in
            name_in:
              type: array
              items:
                type: string
          required:
            - type
            - name_in
        - type: object
          properties:
            type:
              type: string
              const: contacts_phone_number_in
            phone_number_in:
              type: array
              items:
                type: string
              description: >-
                Full phone numbers, matched exactly on digits (formatting like
                +, spaces, and dashes is ignored). Use * inside an entry for
                partial/substring matching.
          required:
            - type
            - phone_number_in
        - type: object
          properties:
            type:
              type: string
              const: contacts_email_in
            email_in:
              type: array
              items:
                type: string
          required:
            - type
            - email_in
        - type: object
          properties:
            type:
              type: string
              const: contacts_attributes_in
            attributes:
              type: array
              items:
                type: object
                propertyNames:
                  type: string
                additionalProperties:
                  type: string
          required:
            - type
        - type: object
          properties:
            type:
              type: string
              const: contacts_affected_by_sequence
            sequence_id:
              type: string
          required:
            - type
            - sequence_id
        - type: object
          properties:
            type:
              type: string
              const: last_contacted_at_between
            after: {}
            before: {}
          required:
            - type
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````

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