# Community Member Search

### API Endpoint

```bash
POST /api/headless/v1/search/community_members
```

### Request Parameters

| Parameter                | Type    | Required | Description                                            |
| ------------------------ | ------- | -------- | ------------------------------------------------------ |
| `filters`                | Array   | No       | Array of filter objects                                |
| `search_text`            | String  | No       | Free text search across member profiles                |
| `per_page`               | Integer | No       | Number of results per page                             |
| `search_after`           | Array   | No       | Cursor for pagination beyond 10K records               |
| `order`                  | String  | No       | Sort order: "oldest", "alphabetical", "latest", "role" |
| `status`                 | String  | No       | Filter by status: "active" or "inactive"               |
| `exclude_empty_profiles` | Boolean | No       | When true, excludes profiles with no data              |
| `exclude_empty_name`     | Boolean | No       | When true, excludes profiles with no name              |

### Building Filters

Each filter in the `filters` array follows this structure:

```json
{
  "key": "string",              // Required
  "filter_type": "string",      // Optional
  "profile_field_type": "string", // Optional, for custom fields
  "profile_field_id": "string", // Optional, for custom fields
  "value": "string",           // Optional
  "gte": "integer",            // Optional, for range queries
  "lte": "integer"             // Optional, for range queries
}
```

#### Available Filter Types

* `"is"` - Exact match
* `"is_not"` - Exclude exact match
* `"contains"`  - Partial match
* `"does_not_contain"`  - Exclude partial match
* `"gt"` - Greater than
* `"lt"`  - Less than
* `"eq"` - Equals to

### Filter Examples

#### Basic Profile Fields

```json
{
  "filters": [
    {
      "key": "name",
      "filter_type": "is",
      "value": "John Doe"
    },
    {
      "key": "email",
      "filter_type": "is",
      "value": "john@example.com"
    },
    {
      "key": "headline",
      "filter_type": "contains",
      "value": "developer"
    }
  ]
}
```

#### Custom Profile Fields

```json
{
  "filters": [
    {
      "key": "profile_field",
      "filter_type": "is",
      "profile_field_type": "text",
      "profile_field_id": "123",
      "value": "Software Engineer"
    },
    {
      "key": "profile_field",
      "profile_field_type": "checkbox",
      "profile_field_id": "456",
      "value": "true"
    }
  ]
}
```

#### Activity Score Range

```json
{
  "filters": [
    {
      "key": "activity_score",
      "gte": 5,
      "lte": 7
    }
  ]
}
```

### Cursor-based Pagination

For datasets larger than 10K records, use cursor-based pagination with `search_after`.

#### Initial Request

```json
{
  "filters": [
    {
      "key": "role",
      "value": "Member"
    }
  ],
  "per_page": 20
}
```

#### Response

```json
{
  "data": [...],
  "next_search_after": ["1463538857"],
  "total_count": 15000
}
```

#### Next Page Request

```json
{
  "filters": [
    {
      "key": "role",
      "value": "Member"
    }
  ],
  "per_page": 20,
  "search_after": ["1463538857"]
}
```

### Combining Filters with Pagination

```json
{
  "filters": [
    {
      "key": "name",
      "filter_type": "contains",
      "value": "John"
    },
    {
      "key": "profile_field",
      "filter_type": "is",
      "profile_field_type": "text",
      "profile_field_id": "123",
      "value": "Engineer"
    }
  ],
  "exclude_empty_profiles": true,
  "status": "active",
  "per_page": 20,
  "search_after": ["1463538857"]
}
```

### Best Practices

1. **Filter Combinations**
   * Combine multiple filters to create precise queries
   * Use text filters (`contains`) for broader matches
   * Use exact matches (`is`) for specific fields like email
2. **Pagination**
   * Use `search_after` for datasets larger than 10K records
   * Keep track of the `next_search_after` value for subsequent requests
   * Start a new query without `search_after` if filters change
3. **Performance**
   * Keep filter combinations reasonable
   * Use `search_text` for general searches across all fields
   * Specify exact fields when possible for better performance

### Common Issues

1. **Invalid Search After**
   * If `search_after` becomes invalid, start a new query without it
   * Always use the most recent `next_search_after` value
2. **No More Results**
   * When `next_search_after` is not in the response, you've reached the end
   * Start a new query if you need to change filters
3. **Filter Combinations**
   * Some filter types may not be available for all fields
   * Check the field type before applying specific filters


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://api.circle.so/apis/headless/member-api/community-member-search.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
