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

# Массовый поиск пользователей

> Поиск нескольких пользователей школы по спискам логинов, Telegram ID или внешних extId

## Заголовки запроса

<ParamField header="Authorization" type="string" required>
  API токен сервисного пользователя в формате Bearer. Получите токен в панели администратора школы. Формат: `Bearer YOUR_TOKEN`.
</ParamField>

<ParamField header="Seller-Id" type="string" required>
  Уникальный идентификатор продавца в системе. Используется для разграничения доступа между разными продавцами.
</ParamField>

<ParamField header="School-Id" type="string" required>
  Уникальный идентификатор школы в системе. Определяет контекст выполнения операции.
</ParamField>

```
POST /saas/v2/user/find-many
```

Требуется аутентификация и право `SchoolManageUsers`.

## Параметры запроса

##### Передайте хотя бы один из списков идентификаторов

<Info>
  Метод возвращает массив найденных пользователей. Пользователи, которых не удалось найти, в ответ не включаются —
  сопоставляйте результат с запросом по `email`/`phone`/`tgId`/`extId` на своей стороне.
</Info>

<ParamField body="logins" type="string[]" required={false}>
  Список логинов пользователей: email, телефон в международном формате или домен `id12345`.
  От 2 до 50 символов каждый, максимум 250 элементов.
</ParamField>

<ParamField body="tgIds" type="integer[]" required={false}>
  Список Telegram ID пользователей. Максимум 250 элементов.
</ParamField>

<ParamField body="extIds" type="string[]" required={false}>
  Список внешних идентификаторов из вашей системы. От 1 до 50 символов каждый, максимум 250 элементов.
</ParamField>

<Warning>
  Необходимо передать **хотя бы один непустой** список. Каждый список ограничен 250 элементами.
</Warning>

<RequestExample>
  ```bash cURL theme={null}
  curl --location 'https://api.exode.biz/saas/v2/user/find-many' \
    --header 'Seller-Id: {{ sellerId }}' \
    --header 'School-Id: {{ schoolId }}' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer YOUR_TOKEN' \
    --data-raw '{
      "logins": ["user@example.com", "+9876543210"]
    }'
  ```

  ```javascript Node.js theme={null}
  const axios = require('axios');

  const findManyUsers = async () => {
    try {
      const response = await axios.post('https://api.exode.biz/saas/v2/user/find-many', {
        logins: ['user@example.com', '+9876543210']
      }, {
        headers: {
          'Seller-Id': '{{ sellerId }}',
          'School-Id': '{{ schoolId }}',
          'Content-Type': 'application/json',
          'Authorization': 'Bearer YOUR_TOKEN'
        }
      });

      console.log('Users found:', response.data.payload.users);
    } catch (error) {
      console.error('Error:', error.response?.data || error.message);
    }
  };

  findManyUsers();
  ```

  ```python Python theme={null}
  import requests
  import json

  url = 'https://api.exode.biz/saas/v2/user/find-many'

  data = {
    'logins': ['user@example.com', '+9876543210']
  }

  headers = {
    'Seller-Id': '{{ sellerId }}',
    'School-Id': '{{ schoolId }}',
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  }

  response = requests.post(url, json=data, headers=headers)
  response.raise_for_status()

  result = response.json()
  print(json.dumps(result['payload']['users'], indent=2, ensure_ascii=False))
  ```
</RequestExample>

<ResponseExample>
  ```json Success theme={null}
  {
    "success": true,
    "code": 201,
    "payload": {
      "users": [
        {
          "id": 1683,
          "createdAt": "2026-07-02T11:15:46.896Z",
          "updatedAt": "2026-07-02T11:15:46.940Z",
          "archivedAt": null,
          "uuid": "e-cjTT0CWMCB",
          "active": true,
          "activated": true,
          "banned": false,
          "alive": true,
          "domain": "id1683",
          "email": "user@example.com",
          "phone": null,
          "tgId": null,
          "vkId": null,
          "appleId": null,
          "extId": "crm_12345",
          "schoolId": 198,
          "language": null,
          "timezone": null,
          "lastOnlineAt": null,
          "starsBalance": 0,
          "currentTime": "2026-07-02T11:15:46+00:00",
          "isSleepingNow": false,
          "profile": {
            "id": 1665,
            "createdAt": "2026-07-02T11:15:46.932Z",
            "updatedAt": "2026-07-02T11:15:46.932Z",
            "archivedAt": null,
            "userId": 1683,
            "official": false,
            "firstName": "Firstname",
            "lastName": "Lastname",
            "fullName": "Firstname Lastname",
            "fullNameShort": "Firstname L.",
            "bdate": null,
            "sex": "Ufo",
            "country": null,
            "city": null,
            "role": "Student",
            "status": null,
            "title": "",
            "emojiTitle": "",
            "avatar": {
              "id": 1665,
              "small": "https://storage.exode.biz/production/user/1683/xK2mVwNib9b0/small/avatar.png",
              "medium": "https://storage.exode.biz/production/user/1683/xK2mVwNib9b0/medium/avatar.png",
              "maximum": "https://storage.exode.biz/production/user/1683/xK2mVwNib9b0/avatar.png"
            },
            "titleState": {
              "manualTitle": null,
              "manualEmojiTitle": null,
              "manualNextTitle": null,
              "manualNextEmojiTitle": null,
              "manualExpiredAt": null,
              "locationTitle": null,
              "locationEmojiTitle": null,
              "achievementTitle": null,
              "achievementEmojiTitle": null
            }
          }
        }
      ]
    }
  }
  ```

  ```json Success - никого не нашли theme={null}
  {
    "success": true,
    "code": 201,
    "payload": {
      "users": []
    }
  }
  ```

  ```json Error - пустой запрос theme={null}
  {
    "cause": "validation",
    "code": 400,
    "success": false,
    "error": "Bad Request",
    "message": [
      "logins should not be empty"
    ]
  }
  ```
</ResponseExample>

## Требования к правам доступа

<Check>
  Для поиска пользователей требуется **право на управление пользователями школы** (`SchoolManageUsers`).
</Check>

<Warning>
  Сервисный пользователь должен быть аутентифицирован по токену и иметь соответствующие права доступа к указанной
  школе.
</Warning>
