Темный режим

4. API интеграция

4.1. Описание API endpoints

HRoom предоставляет комплексный набор REST API endpoints для взаимодействия с различными частями системы. Все API endpoints организованы по функциональным модулям и имеют единый формат ответов.

Базовый URL API

Все API запросы выполняются к базовому URL: https://api.hroom.ai/webhook/

Основные API endpoints

Аутентификация и пользователи

Endpoint Метод Описание Параметры Auth Формат ответа
/auth/login POST Аутентификация пользователя email, password -
JSON
{
  "company_token": "0vf00e55-352a-49d9-afba-008534388a89",
  "status": "success",
  "manager_token": "3vfbb154-a59f-4be0-a72e-dd99d4307601"
}
/auth/signup POST Регистрация нового пользователя email, password, firstName, lastName, companyName, phone -
JSON
{
  "response": "email already exists"
}
{
  "response": "company already exists"
}
{
  "response": "success"
}
/auth/activation GET Активация аккаунта по ссылке из email token -
JSON
{
   "activated": true
}
{
  "token": "already-activated"
}
{
  "token": "expired"
}
{
  "token": "error"
}
/auth/activation-retry GET Повторная отправка письма активации email -
JSON
{
  "success": true
}
/auth/reset POST Запрос на сброс пароля email -
JSON
{
  "success": true
}
{
  "status": "active"
}
{
  "status": "expired"
}                                      
/auth/newpass POST Установка нового пароля после сброса token, password -
JSON
{
  "status": "success"
}
{
  "status": "expired"
}                                        

Метрики и аналитика

Endpoint Метод Описание Параметры Auth Формат ответа
/teams/metric/get GET Получение метрик команды curdate [6m, 3m, 1m], paramNameMetric company_token
JSON
[
  {
    "departmentId": 3,
    "metrics": {
      "wellness": 6.4,
      "happiness": 8.1,
      "alignment": 6.9,
      "relationship_with_peers": 7.3,
      "relationship_with_manager": 7.4,
      "feedback": 6.7,
      "personal_growth": 8.3,
      "recognition": 7,
      "satisfaction": 7.1,
      "ambassadorship": 7.2
    },
    "engagement_score": 7.2,
    "absolute_changes_by_metric": {
      "wellness": -0.5,
      "happiness": -0.3,
      "alignment": -0.5,
      "relationship_with_peers": -0.3,
      "relationship_with_manager": -0.4,
      "feedback": -0.4,
      "personal_growth": 0,
      "recognition": -0.5,
      "satisfaction": -0.4,
      "ambassadorship": -0.6,
      "engagement_score": -0.4
    },
    "name": "Тестовый отдел"
  },..
/metric/dynamic/get GET Получение динамики изменения метрик - company_token
JSON
[
  {
    "grouping_period": "week",
    "overall_period": "3 months",
    "metric_scores_by_period": {
      "wellness": {
        "25.11.24-02.12.24": 6.3,
        "02.12.24-09.12.24": 6,
        "09.12.24-16.12.24": 9,
        "27.01.25-03.02.25": 6.6,
        "03.02.25-10.02.25": 7.1,
        "17.02.25-24.02.25": 5.3,
        "10.03.25-17.03.25": 6.7
      },
      "happiness": {
        "25.11.24-02.12.24": 8,
        "02.12.24-09.12.24": 6.2,
        "09.12.24-16.12.24": 9.9,
        "27.01.25-03.02.25": 9.3,
        "03.02.25-10.02.25": 10,
        "17.02.25-24.02.25": 8.3,
        "10.03.25-17.03.25": 6.8
      },
      "alignment": {
        "25.11.24-02.12.24": 6.8,
        "02.12.24-09.12.24": 6.2,
        "09.12.24-16.12.24": 9,
        "27.01.25-03.02.25": 6.5,
        "03.02.25-10.02.25": 7.5,
        "17.02.25-24.02.25": 6.9,
        "10.03.25-17.03.25": 6.7
      },
      "relationship_with_peers": {
        "25.11.24-02.12.24": 7.1,
        "02.12.24-09.12.24": 6.7,
        "09.12.24-16.12.24": 9.6,
        "27.01.25-03.02.25": 8.1,
        "03.02.25-10.02.25": 5.5,
        "17.02.25-24.02.25": 7.5,
        "10.03.25-17.03.25": 6.7
      },
      "relationship_with_manager": {
        "25.11.24-02.12.24": 7.5,
        "02.12.24-09.12.24": 6.6,
        "09.12.24-16.12.24": 8.8,
        "27.01.25-03.02.25": 7.7,
        "03.02.25-10.02.25": 10,
        "17.02.25-24.02.25": 6.1,
        "10.03.25-17.03.25": 6.7
      },
      "feedback": {
        "25.11.24-02.12.24": 6.6,
        "02.12.24-09.12.24": 7.2,
        "09.12.24-16.12.24": 8.3,
        "27.01.25-03.02.25": 6.4,
        "03.02.25-10.02.25": 4.2,
        "17.02.25-24.02.25": 5.3,
        "10.03.25-17.03.25": 6.7
      },
      "personal_growth": {
        "25.11.24-02.12.24": 8.5,
        "02.12.24-09.12.24": 6.6,
        "09.12.24-16.12.24": 7.5,
        "27.01.25-03.02.25": 8.5,
        "03.02.25-10.02.25": 4,
        "17.02.25-24.02.25": 8.5,
        "10.03.25-17.03.25": 6.7
      },
      "recognition": {
        "25.11.24-02.12.24": 6.9,
        "02.12.24-09.12.24": 6.6,
        "09.12.24-16.12.24": 8.9,
        "27.01.25-03.02.25": 6.8,
        "03.02.25-10.02.25": 8.8,
        "17.02.25-24.02.25": 8.1,
        "10.03.25-17.03.25": 6.7
      },
      "satisfaction": {
        "25.11.24-02.12.24": 7.1,
        "02.12.24-09.12.24": 6.3,
        "09.12.24-16.12.24": 8.8,
        "27.01.25-03.02.25": 7.2,
        "03.02.25-10.02.25": 8.6,
        "17.02.25-24.02.25": 6.1,
        "10.03.25-17.03.25": 6.7
      },
      "ambassadorship": {
        "25.11.24-02.12.24": 7.4,
        "02.12.24-09.12.24": 7.6,
        "09.12.24-16.12.24": 8.7,
        "27.01.25-03.02.25": 7,
        "03.02.25-10.02.25": 5,
        "17.02.25-24.02.25": 7.3,
        "10.03.25-17.03.25": 6.7
      }
    },
    "final_scores_by_metric": {
      "wellness": 7,
      "happiness": 7.3,
      "alignment": 6.7,
      "relationship_with_peers": 7.4,
      "relationship_with_manager": 7.4,
      "feedback": 7.2,
      "personal_growth": 7.5,
      "recognition": 6.7,
      "satisfaction": 6.9,
      "ambassadorship": 7.6
    },
    "absolute_changes_by_metric": {
      "wellness": 0.4,
      "happiness": 0.4,
      "alignment": 0.4,
      "relationship_with_peers": 0.3,
      "relationship_with_manager": 0.4,
      "feedback": 0.4,
      "personal_growth": 0.3,
      "recognition": 0.4,
      "satisfaction": 0.4,
      "ambassadorship": 0.3
    }
  }
]
/metric/score GET Получение общего показателя метрики - company_token
JSON
[
  {
    "overallEngagementScore": 72,
    "engagementLevel": "Высокий",
    "engagementScoreLast150Days": 68,
    "engagementScoreChangePercentage": 4,
    "market_avg": 69,
    "market_avg_description": "Выше рынка на 3%",
    "market_avg_state": "good",
    "enps_score": 50,
    "enps_description": "Хороший"
  },
  {
    "engagementValues": [
      {
        "metric": "Невовлечённые",
        "count": 1,
        "percentage": 10,
        "description": "Сотрудники с оценками от 0 до 3.3 баллов"
      },
      {
        "metric": "Слабо вовлечённые",
        "count": 2,
        "percentage": 20,
        "description": "Сотрудники с оценками от 3.4 до 6.6 баллов"
      },
      {
        "metric": "Вовлечённые",
        "count": 7,
        "percentage": 70,
        "description": "Сотрудники с оценками от 6.7 до 10 баллов"
      }
    ]
  },
  {
    "participation": 10
  },
  {
    "respondents": 17
  }
]

Вопросы и опросы

Endpoint Метод Описание Параметры Auth Формат ответа
/questions/get POST Получение списка вопросов departmentId, paramNameMetric company_token
JSON
[
  {
    "questionId": 80,
    "totalUserCount": 1,
    "averageValue": 5,
    "groupCounts": {
      "Отрицательно": 0,
      "Нейтрально": 1,
      "Положительно": 0,
      "Без ответа": 0
    },
    "groupPercentages": {
      "Отрицательно": 0,
      "Нейтрально": 100,
      "Положительно": 0,
      "Без ответа": 0
    },
    "questionRussian": "Подход нашей компании к принятию решений соответствует нашим корпоративным ценностям.",
    "paramNameMetric": "alignment",
    "paramNameSubmetric": "values",
    "key": "values",
    "paramNameMetricRu": "Соответствие ценностям",
    "paramNameSubmetricRu": "Ценности"
  },...
/surveys/get POST Получение списка опросов - company_token
JSON
[
  {
    "surveyId": 5,
    "name": "Опрос вовлеченности",
    "auditory": {
      "departmentIds": [
        11,
        13
      ]
    },
    "respondents": [
      13,
      3,
      4,
      7,
      10,
      11,
      12,
      16
    ],
    "type": "q20",
    "groupIndex": 1,
    "test": false,
    "status": "completed",
    "start_date": "2024-12-06T17:10:00.000Z",
    "end_date": "2024-12-13T17:10:00.000Z",
    "createdAt": "2024-12-07T17:11:02.625Z",
    "total_respondents_count": 8,
    "current_respondents_count": 8
  },...
/surveys/create POST Создание нового опроса name, status [planned, draft], type [q20, q5], test [Boolean], start_date, end_date, auditory [{"departmentIds": []}] company_token
JSON
{
  "status": "success"
}
{
  "status": "need respondents"
}
/surveys/delete POST Удаление опроса surveyId company_token
JSON
{
  "status": "success"
}
/surveys/update POST Обновление данных опроса surveyId, name, status [planned, draft], type [q20, q5], test [Boolean], start_date, end_date, auditory [{"departmentIds": []}] company_token
JSON
{
  "status": "success"
}
{
  "status": "need respondents"
}
                                        
/surveys/complete POST Завершение опроса surveyId company_token
JSON
-
/surveys/count POST Получение количества опросов по компании - company_token
JSON

[
{
"surveys_count": 
6
}
]
/survey/data/get GET Получение данных опроса surveyId(uuid),userId(uuid) -
JSON
[
  {
    "questions": [
      {
        "hint": null,
        "type": "radio-5pt",
        "answer": [
          "Совершенно не согласен",
          "Не согласен",
          "Нейтрально",
          "Согласен",
          "Полностью согласен"
        ],
        "question": "Мои коллеги показывают высокий уровень профессионализма в своей работе",
        "questionId": 38,
        "paramNameMetric": "relationship_with_peers",
        "paramNameSubmetric": "trust_between_peers"
      },...
  },
  {
    "question_list": [
      38,
      99,
      20,
      65,...
    ],
    "lang": "ru",
    "companyname": "HRoom"
  },
  {
    "surveyId": 3,
    "name": "Опрос вовлеченности",
    "respondents": [
      5
    ],
    "type": "q20",
    "groupIndex": 1,
    "test": false,
    "companyId": 1,
    "userId": 5,
    "departmentId": 3,
    "lang": "ru",
    "status": "success",
    "result": "success"
  }
]

Сотрудники и отделы

Endpoint Метод Описание Параметры Auth Формат ответа
/employees/get POST Получение списка сотрудников departmentId, status, hireDate, searchTerm, userId company_token
JSON
[
  {
    "departmentId": 2,
    "userId": 12,
    "firstName": "Сотрудник",
    "lastName": "Тестовый",
    "middleName": null,
    "email": "anatoli.hroom@gmail.com",
    "phone": "9602308782",
    "telegram": null,
    "gender": "male",
    "role": "Тестовая должность",
    "birthDate": "1985-01-01T00:00:00.000Z",
    "hireDate": "2022-10-05T00:00:00.000Z",
    "city": "СПБ",
    "status": "active",
    "department_name": "Доставка"
  },...
/employees/count POST Получение количества сотрудников в компании - company_token
JSON
{
  "employee_count": 15
}
/employees/create POST Создание нового сотрудника lastName, firstName, middleName, role, city, birthDate, hireDate, gender, phone, email, telegram, departmentId, status company_token
JSON
[
  {
    "success": true
  }
]
[
  {
    "response": "the limit has been reached"
  }
]
 
/employees/delete POST Удаление сотрудника userId company_token
JSON
{
  "status": "success"
}
/employees/update POST Обновление данных сотрудника lastName, firstName, middleName, role, city, birthDate, hireDate, gender, phone, email, telegram, departmentId, status, userId company_token
JSON
{
  "response": "email already exists"
}
[
  {
    "success": true
  }
]
/employees/import POST Массовый импорт сотрудников file[csv/xlsx] company_token
JSON
{
  "result": "success"
}
/departments/get POST Получение списка отделов компании heads[true/false] company_token
JSON
[
  {
    "departmentId": 11,
    "name": "Дизайн",
    "headId": 13,
    "head_name": "Бурцев Анатолий"
  },
  {
    "departmentId": 12,
    "name": "Разработка",
    "headId": 13,
    "head_name": "Бурцев Анатолий"
  },
  {
    "departmentId": 9,
    "name": "Наша команда",
    "headId": null,
    "head_name": ""
  },...
/departments/create POST Создание нового отдела name, headid company_token
JSON
{
  "status": "success"
}
/departments/delete POST Удаление отдела departmentId company_token
JSON
{
  "status": "success"
}
/departments/update POST Обновление данных отдела departmentId, name, headid company_token
JSON
{
  "status": "success"
}

Профиль и настройки

Endpoint Метод Описание Параметры Auth Формат ответа
/profile/personal/get POST Получение личных данных пользователя - manager_token
JSON
[
  {
    "managerId": 65,
    "email": "dstan1111@gmail.com",
    "firstName": "Анатолий",
    "middleName": "Александрович",
    "lastName": "Бурцев",
    "phone": "79602308782",
    "photoUrl": "https://s3.timeweb.cloud/91b8f4fa-91527ce1-dcc1-4e74-87bf-8264ca7c7368/avatar/avatar_1741030626184.jpg",
    "companyId": 1,
    "admin": true
  }
]
/profile/personal/save POST Сохранение личных данных пользователя managerid, firstname, lastname, middlename, phone manager_token
JSON
[
  {
    "success": true
  }
]
/profile/company/get POST Получение данных компании пользователя - company_token
JSON
[
  {
    "companyId": 1,
    "name": "HRoom",
    "accountType": "paid",
    "website": "https://www.hroom.ai"
  }
]
/profile/company/save POST Сохранение данных компании ncompanyId, name, website, billingInfo: { "legalAddress", "actualAddress", "kpp", "inn", "ogrn", "bankAccount", "corrAccount", "bik", "bankName" } manager_token
JSON
[
  {
    "success": true
  }
]
/profile/company/billing/get POST Получение платежных данных компании - company_token
JSON
[
  {
    "companyId": 1,
    "billing_info": {
      "bik": "sfd",
      "inn": "sdf",
      "kpp": "sdf",
      "ogrn": "sdf",
      "bankName": "sfd",
      "bankAccount": "sdf",
      "corrAccount": "sfd",
      "legalAddress": "sdf",
      "actualAddress": "sdf"
    }
  }
]
/profile/company/billing/save POST Сохранение платежных данных компании billingInfo: { "legalAddress", "actualAddress", "kpp", "inn", "ogrn", "bankAccount", "corrAccount", "bik", "bankName" } company_token
JSON
[
  {
    "success": true
  }
]
/profile/file/upload POST Загрузка файла (аватар, лого и т.д.) file (image) manager_token
JSON
{
  "success": true
}
/unsubscribe GET Отписка от рассылок token (user uuid) or manager_token (uuis), action (true/false), status -
JSON
[
  {
    "status": {
      "result": true,
      "system": true
    },
    "user": "manager"
  }
]
                                          [
  {
    "user": "employee",
    "status": "active"
  }
]
                                        

AI рекомендации и инсайты

Endpoint Метод Описание Параметры Auth Формат ответа
/ai/get GET Получение ИИ советов/инсайтов departmentId, type, paramNameMetric company_token
JSON
[
  {
    "id": 3686,
    "companyId": 1,
    "departmentId": 1,
    "paramNameMetric": "ambassadorship",
    "paramNameSubmetric": null,
    "priority": "important",
    "read": false,
    "type": "advice",
    "shortValue": "Укрепите внутренний бренд, регулярно рассказывая о достижениях компании и вкладе отдела. Это повысит гордость за организацию.",
    "longValue": null,
    "createdAt": "2025-03-10T00:00:00.000Z",
    "updatedAt": "2025-03-10T00:00:00.000Z",
    "surveyId": 5,
    "questions": [
      10,
      14
    ],
    "name": "Все команды",
    "paramNameMetricRu": "Бренд работодателя"
  },
/ai/get/long GET Получение детальной информации по ИИ совету/инсайту ai_data_id company_token
JSON
[
  {
    "id": 4375,
    "companyId": 1,
    "departmentId": 1,
    "paramNameMetric": "personal_growth",
    "paramNameSubmetric": null,
    "priority": "important",
    "read": true,
    "type": "insight",
    "shortValue": "50% сотрудников не чувствуют, что компания поддерживает их рост и развитие, что может ограничивать их профессиональный прогресс.",
    "longValue": "

Половина сотрудников отдела (50%) не ответили на вопрос о поддержке их роста и развития, что может указывать на недостаточную вовлеченность или отсутствие четкого понимания, как компания способствует их профессиональному прогрессу. Это может быть сигналом к тому, что процессы, связанные с развитием сотрудников, либо недостаточно прозрачны, либо не воспринимаются как значимые.

\n\n
\n\n

Средний балл по вопросу составляет 6.5, что ниже ожидаемого уровня удовлетворенности. Это говорит о том, что даже среди ответивших сотрудников уровень поддержки роста и развития оценивается как умеренный. Такая оценка может быть связана с отсутствием четких программ развития, недостаточным количеством обратной связи или ограниченными возможностями для обучения и карьерного роста.

\n\n
\n\n

Отсутствие ответа от одного из сотрудников (50%) может также указывать на возможное выгорание или отсутствие мотивации участвовать в опросах, что требует дополнительного внимания к вовлеченности и эмоциональному состоянию коллектива.

", "createdAt": "2025-03-13T00:00:00.000Z", "updatedAt": "2025-03-13T00:00:00.000Z", "surveyId": 3, "questions": [ 117 ], "departmentName": "Все команды", "paramNameMetricRu": "Личностный рост" } ]

Администрирование

Endpoint Метод Описание Параметры Auth Формат ответа
/company/get POST Получение списка компаний companyId (all, id) manager_token
JSON
[
  {
    "companyId": 78,
    "name": "SYNAPTECH",
    "accountType": "free",
    "website": null,
    "expirationDate": null,
    "token": "7b7eec86-bd5e-5a24-a064-9dc17b43169c",
    "createdAt": "2025-03-19T05:56:15.719Z",
    "managers": [
      {
        "admin": false,
        "email": "i@maksimbelousov.ru",
        "phone": "79139139095",
        "lastName": "Белоусов ",
        "photoUrl": null,
        "firstName": "Максим ",
        "managerId": 84,
        "middleName": null
      }
    ]
  },...
/company/add POST Добавление новой компании name, accountType, website, expirationDate manager_token
JSON
[
  {
    "success": true
  }
]
/company/update POST Обновление данных компании name, accountType, website, expirationDate manager_token
JSON
[
  {
    "success": true
  }
]
/company/delete POST Удаление компании companyId manager_token
JSON
[
  {
    "success": true
  }
]
/managers/get POST Получение списка HR-менеджеров companyId, isActive, search, page, limit, sortBy, sortDirection manager_token
JSON
[  {
    "managerId": 65,
    "email": "dstan1111@gmail.com",
    "firstName": "Анатолий",
    "middleName": "Александрович",
    "lastName": "Бурцев",
    "phone": "79902308782",
    "photoUrl": "https://s3.timeweb.cloud/91b8f4fa-91827ce1-dcc1-4e74-87bf-8264ca7c7368/avatar/avatar_1741030626184.jpg",
    "companyId": 1,
    "admin": true,
    "manager_token": "3efbb514-a99f-4be0-a72e-dd99d4307601",
    "name": "HRoom",
    "accountType": "paid",
    "website": "https://www.hroom.ai",
    "expirationDate": "2025-10-28T00:00:00.000Z",
    "company_token": "0bf05e15-302a-49d9-afba-008534388a89",
    "createdAt": "2024-11-08T02:51:23.031Z"
  },...
/managers/add POST Добавление нового HR-менеджера firstname, lastname, middlename, phone, companyId, email manager_token
JSON
[
  {
    "success": true
  }
]
{
  "response": "email already exists"
}
/managers/update POST Обновление данных HR-менеджера managerid, firstname, lastname, middlename, phone, companyId, email manager_token
JSON
[
  {
    "success": true
  }
]
/managers/delete POST Удаление HR-менеджера managerid manager_token
JSON
[
  {
    "success": true
  }
]
/translations/get GET Получение переводов интерфейса key, type company_token
JSON
[
  {
    "key": "recognition",
    "ru": "Признание заслуг"
  },
  {
    "key": "personal_growth",
    "ru": "Личностный рост"
  },...

4.2. Аутентификация запросов

Все API-запросы к HRoom (кроме публичных endpoints) требуют аутентификации. HRoom использует механизм JWT-токенов для авторизации и аутентификации запросов.

Получение токена

Для получения токена необходимо выполнить авторизацию через эндпоинт /auth/login:


// Пример запроса авторизации
const loginResponse = await fetch('https://api.hroom.ai/webhook/auth/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    email: 'user@example.com',
    password: 'password123'
  })
});

// Получение токенов из ответа
const authData = await loginResponse.json();
const companyToken = authData.company_token; // Токен компании для доступа к общим данным
const managerToken = authData.manager_token; // Токен HR-менеджера для управления ресурсами

// Сохранение токенов в localStorage
localStorage.setItem('companyToken', companyToken);
localStorage.setItem('managerToken', managerToken);

Использование токена в запросах

Полученные токены необходимо включать в заголовок Authorization запросов. В зависимости от endpoint следует использовать либо company_token, либо manager_token:


// Пример запроса с авторизацией через company_token
const response = await fetch('https://api.hroom.ai/webhook/teams/metric/get', {
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('companyToken')}`,
    'Content-Type': 'application/json'
  }
});

// Пример запроса с авторизацией через manager_token
const surveysResponse = await fetch('https://api.hroom.ai/webhook/surveys/get', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('managerToken')}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    status: 'ACTIVE'
  })
});

Хранение токенов

В приложении HRoom токены сохраняются в localStorage для использования между сессиями:


// Сохранение токенов в localStorage
localStorage.setItem('companyToken', companyToken);
localStorage.setItem('managerToken', managerToken);

// Получение токенов из localStorage
const companyToken = localStorage.getItem('companyToken');
const managerToken = localStorage.getItem('managerToken');

Однако стоит помнить о потенциальных рисках безопасности при хранении токена в localStorage. В более критичных с точки зрения безопасности сценариях можно рассмотреть использование sessionStorage или HTTP-only куки.

Обновление токена

JWT-токены имеют ограниченный срок действия. После истечения срока действия токена необходима повторная авторизация пользователя. Система отслеживает состояние токена и перенаправляет пользователя на страницу входа при получении ошибки 401 (Unauthorized).

Использование API-клиента с интерцепторами

В HRoom используется централизованный API-клиент, который автоматически добавляет токен к каждому запросу:


// Пример API-клиента с интерцепторами для авторизации
const apiClient = {
  async request(url, options = {}) {
    // Определяем, какой токен использовать в зависимости от endpoint
    let token;
    if (url.includes('/teams/') || url.includes('/metric/')) {
      token = localStorage.getItem('companyToken');
    } else {
      token = localStorage.getItem('managerToken');
    }
    
    const headers = {
      'Content-Type': 'application/json',
      ...options.headers
    };
    
    if (token) {
      headers.Authorization = `Bearer ${token}`;
    }
    
    const config = {
      ...options,
      headers
    };
    
    try {
      const response = await fetch(`https://api.hroom.ai/webhook${url}`, config);
      
      // Обработка ошибки авторизации
      if (response.status === 401) {
        localStorage.removeItem('companyToken');
        localStorage.removeItem('managerToken');
        window.location.href = '/auth/login';
        return Promise.reject(new Error('Unauthorized'));
      }
      
      return response;
    } catch (error) {
      console.error('API request failed:', error);
      throw error;
    }
  },
  
  // GET запрос
  async get(url, options = {}) {
    return this.request(url, { ...options, method: 'GET' });
  },
  
  // POST запрос
  async post(url, data, options = {}) {
    return this.request(url, {
      ...options,
      method: 'POST',
      body: JSON.stringify(data)
    });
  },
};