Введение
Добро пожаловать в API Scanderm! Эта документация предоставляет всю необходимую информацию для интеграции с нашей платформой анализа кожи и рекомендации продуктов.
Возможности интеграции
Базовый пользовательский путь
Система Scanderm включает пять обязательных этапов интеграции, которые обеспечивают полный цикл анализа и получения рекомендаций:
Обязательные этапы интеграции:
Инициализация сессии - создание новой сессии с указанием типа анализа (test_type от 1 до 5). Этот этап подготавливает систему к получению и обработке данных в соответствии с выбранным типом анализа.
Загрузка фотографии - передача изображения в систему для анализа с использованием алгоритмов компьютерного зрения. Поддерживаются форматы JPEG и PNG с максимальным размером файла 5 МБ.
Получение текстовых результатов - формирование структурированных результатов анализа с указанием выявленных проблем, их степени выраженности и рекомендаций по устранению.
Генерация визуализаций - создание графических представлений результатов анализа, включающих диаграммы состояния, карты проблемных зон и сравнительные визуализации.
Формирование рекомендаций продуктов - автоматический подбор косметических средств из каталога с учетом выявленных особенностей и потребностей пользователя.
Важное примечание: Эти пять этапов обязательны для корректной работы системы. Дополнительные функции (управление корзиной, детализация продуктов, экспорт результатов, управление профилем) можно реализовать по необходимости.
Требования к продуктовой базе данных
Для корректной работы рекомендательных алгоритмов необходимо предоставить структурированный каталог косметических продуктов со следующими техническими требованиями:
Обязательные поля:
- Уникальный идентификатор (product_id/code) - любой уникальный код для идентификации товара в системе партнера
- Состав продукта (composition/ingredients) - полный перечень компонентов согласно номенклатуре INCI (International Nomenclature of Cosmetic Ingredients) или эквивалентной классификации
Дополнительные поля для расширенного функционала:
- Ценовая информация (price)
- Брендовая принадлежность (brand)
- Объем/вес упаковки (volume/weight)
- Категориальная классификация (category)
- Страна происхождения (country)
- Описание эффектов (effects)
- Инструкции по применению (usage_instructions)
- URL изображения продукта (image_url)
Автоматическая категоризация и анализ продуктов
Система Scanderm включает модуль автоматической разметки косметических средств, работающий на основе базы данных косметических компонентов, которая содержит более 40,000 активных и вспомогательных веществ с характеристиками их свойств и воздействия на кожу.
Процесс автоматической категоризации включает:
- Парсинг и анализ состава продукта с идентификацией всех компонентов по международным номенклатурам
- Автоматическое определение функциональной категории продукта (очищающее, увлажняющее, антивозрастное и т.д.)
- Классификацию по типам кожи и проблемам, для решения которых предназначен продукт
- Расчет индекса совместимости с различными состояниями кожи на основе синергетического воздействия компонентов
Этот механизм обеспечивает точность рекомендательных алгоритмов без необходимости предварительной ручной категоризации продуктового каталога партнера, упрощая процесс интеграции и снижая временные затраты на подготовку данных.
Обзор API
API Scanderm организовано в соответствии с принципами REST. Все конечные точки API доступны через HTTPS и возвращают данные в формате JSON. API разработано для простоты использования и следует последовательным паттернам.
Базовый URL
Все конечные точки API используют переменную HOST, которую следует заменить базовым URL, предоставленным при настройке вашего аккаунта.
Структура API
Наш API организован по следующим ключевым функциональным областям:
- Аутентификация - Конечные точки для регистрации пользователей, получения токенов и обновления доступа
- Профиль пользователя - Управление информацией и предпочтениями пользователя
- Тестирование - Загрузка фотографий для анализа и заполнение опросников
- Результаты тестов - Получение результатов анализа и рекомендаций по продуктам
- Магазины - Поиск и выбор розничных точек
- Продукты - Просмотр и поиск продуктов
- Корзина покупок - Управление выбранными продуктами для покупки
Типы тестов
API поддерживает следующие типы тестов, каждый из которых требует специфической фотографии и набора вопросов:
- test_type=1 - Анализ кожи лица
- test_type=2 - Анализ состояния волос
- test_type=3 - Анализ состояния зубов
- test_type=4 - Анализ состояния языка
- test_type=5 - Анализ ногтей
Каждый тип теста имеет свой набор специфических параметров и возвращает соответствующие результаты.
Изменения в этой версии
API было оптимизировано для уменьшения дублирования и повышения производительности:
- Консолидированы конечные точки для результатов тестов для уменьшения количества вызовов
- Добавлена пагинация для списков продуктов и магазинов
- Оптимизированы списки продуктов для отображения основной информации в списках
- Добавлена более подробная информация о продуктах в специальной конечной точке детализации
- Улучшены возможности фильтрации для продуктов и магазинов
- Расширены коды ошибок и ответы
Ограничение частоты запросов
API реализует многоуровневое ограничение частоты запросов для предотвращения злоупотреблений и DDoS-атак. Ограничения скорости различаются в зависимости от конечной точки и основаны на количестве запросов в минуту, в час и в день. Когда ограничение скорости превышено, API вернет ответ 429 Too Many Requests.
Система ограничения использует комбинацию следующих факторов: - IP-адрес отправителя запроса - Токен аутентификации (при наличии) - Тип конечной точки (эндпоинта) - Общая нагрузка на систему в данный момент
Ответ будет включать следующие заголовки:
- X-RateLimit-Limit: Максимальное количество запросов, разрешенных в текущем временном окне
- X-RateLimit-Remaining: Количество оставшихся запросов в текущем временном окне
- X-RateLimit-Reset: Время, в которое текущее окно ограничения скорости сбрасывается, в секундах эпохи Unix
- Retry-After: Рекомендуемое время ожидания (в секундах) перед повторной попыткой запроса
Для защиты от DDoS-атак система также может динамически снижать лимиты при обнаружении аномальной активности и применять прогрессивную задержку ответа при многократном превышении лимитов.
Безопасность
Все запросы API должны выполняться через HTTPS. HTTP-запросы будут отклонены.
Файлы изображений надежно хранятся в Yandex Cloud S3 с доступом через подписанные URL. Все URL изображений истекают через один час в целях безопасности. Если вам нужно получить доступ к изображению после истечения срока действия URL, вам потребуется запросить новый URL.
Токены API следует хранить в безопасности и никогда не делиться ими. Если токен скомпрометирован, его следует немедленно аннулировать, запросив новый токен.
Scanderm реализует стандартные меры безопасности во всем API, включая:
- TLS 1.2+ для безопасной передачи данных
- Аутентификация на основе JWT-токенов с коротким сроком действия
- Авторизационные потоки, соответствующие OAuth 2.0
- Ограничения CORS для предотвращения несанкционированных межсайтовых запросов
- Ограничение скорости для предотвращения атак методом перебора
- Проверка и очистка ввода для защиты от атак внедрения
- Регулярные аудиты безопасности и проверка на проникновение
Лучшие практики безопасности
При интеграции с API Scanderm следуйте этим лучшим практикам для поддержания безопасной среды:
- Храните токены API безопасно, никогда в клиентском коде или localStorage
- Реализуйте правильные механизмы обновления токенов
- Проверяйте весь пользовательский ввод перед отправкой в API
- Следуйте принципу наименьших привилегий при запросе доступа к конечным точкам
- Реализуйте правильную обработку ошибок, которая не раскрывает конфиденциальную информацию
- Отслеживайте использование API на предмет необычных паттернов, которые могут указывать на компрометацию
- Поддерживайте библиотеки интеграции в актуальном состоянии с патчами безопасности
Справочник объектов API
В этом разделе описаны стандартные объекты, используемые во всем API. Эти структуры объектов упоминаются в различных конечных точках для обеспечения согласованности.
Объект пользователя
{
"id": 4,
"username": "test@test.ru",
"phone": "79111231234",
"first_name": "First",
"last_name": "Last",
"birthdate": "1992-01-01",
"gender": 1,
"city": "Санкт-Петербург"
}
Поля объекта пользователя
| Field | Type | Description |
|---|---|---|
| id | Integer | Уникальный идентификатор пользователя |
| username | String | Адрес электронной почты пользователя, используемый для входа |
| phone | String | Номер телефона пользователя с кодом страны |
| first_name | String | Имя пользователя |
| last_name | String | Фамилия пользователя |
| birthdate | String | Дата рождения пользователя в формате ГГГГ-ММ-ДД |
| gender | Integer | Пол пользователя (1 = мужской, 2 = женский, 0 = не указан) |
| city | String | Город проживания пользователя |
Объект продукта
{
"id": 331,
"code": "1000273642",
"name": "LAF Маска для лица Глубокое увлажнение с гиалуроновой кислотой 2х7мл",
"brand": "laf",
"price": 69.98,
"category": 1,
"stage": 32,
"price_segment": 2,
"priority": 2,
"img": "https://storage.yandexcloud.net/bsmain/media/products/1000273642.jpeg",
"value": "2x7мл",
"country": "Россия",
"description": "В составе маски высокоэффективные компоненты: гиалуроновая кислота, водорастворимый хитозан и провитамин В5 глубоко увлажняют, разглаживают и тонизирует кожу. Водоросли замедляют процессы старения, а также моделируют овал лица.",
"effect": "Увлажнение, разглаживание, тонизирование кожи, замедление процессов старения",
"how_to_use": "Нанесите на очищенную кожу лица, избегая области вокруг глаз, оставьте на 15-20 минут, затем смойте теплой водой.",
"spec": "Aqua, Glycerin, Panthenol, Chitosan, Sodium Hyaluronate, Laminaria Digitata Extract, Phenoxyethanol, Ethylhexylglycerin, Parfum, Citric Acid",
"components": [
{
"name": "гиалуроновая кислота",
"description": "sodium hyaluronate"
},
{
"name": "провитамин В5",
"description": "panthenol"
},
{
"name": "хитозан",
"description": "chitosan"
}
],
"in_stock": true,
"quantity": 25,
"confirmation_level": 0.87
}
Поля объекта продукта
| Field | Type | Description |
|---|---|---|
| id | Integer | Уникальный идентификатор продукта |
| code | String | Код/артикул продукта |
| name | String | Название продукта |
| brand | String | Название бренда (в нижнем регистре) |
| price | Float | Цена продукта |
| category | Integer | ID категории продукта |
| stage | Integer | ID этапа ухода |
| price_segment | Integer | Ценовой сегмент (1=бюджетный, 2=средний, 3=премиум) |
| priority | Integer | Приоритет продукта/уровень рекомендации |
| img | String | Защищенный URL S3 на изображение продукта (срок действия истекает через 1 час) |
| value | String | Объем/вес продукта |
| country | String | Страна происхождения |
| description | String | Подробное описание продукта |
| effect | String | Эффекты/преимущества продукта |
| how_to_use | String | Инструкции по использованию |
| spec | String | Список ингредиентов продукта |
| components | Array | Ключевые активные ингредиенты |
| components[].name | String | Название компонента на русском языке |
| components[].description | String | Название компонента на английском/INCI |
| in_stock | Boolean | Статус наличия |
| quantity | Integer | Доступное количество |
| confirmation_level | Float | Оценка уверенности рекомендации (0-1) |
Объект магазина
{
"id": 937719,
"city": "Москва",
"address": "Москва, Серпуховский Вал ул, 6",
"worktime": "10:00 - 22:00",
"description": "Крупный магазин с широким ассортиментом косметики",
"point": "55.712208, 37.618048",
"test_type": 1,
"available_products_count": 856,
"features": ["parking", "wifi", "consultant"],
"images": [
"https://storage.yandexcloud.net/bsmain/media/shops/937719_1.jpeg",
"https://storage.yandexcloud.net/bsmain/media/shops/937719_2.jpeg"
]
}
Поля объекта магазина
| Field | Type | Description |
|---|---|---|
| id | Integer | Уникальный идентификатор магазина |
| city | String | Город, где находится магазин |
| address | String | Полный адрес магазина |
| worktime | String | Часы работы магазина |
| description | String | Описание магазина |
| point | String | Географические координаты (широта, долгота) |
| test_type | Integer | Тип тестов, доступных в этом магазине |
| available_products_count | Integer | Количество доступных продуктов в этом магазине |
| features | Array | Список доступных функций в этом магазине |
| images | Array | URL изображений магазина (если доступны) |
Аутентификация
Токены
API Scanderm использует JWT-токены для аутентификации. Существуют три типа токенов:
- Временный токен: Краткосрочный токен для пользователей без учетной записи
- Токен доступа: Используется для обычных аутентифицированных запросов
- Токен обновления: Используется для получения нового токена доступа, когда срок действия текущего истекает
Все аутентифицированные запросы должны включать токен в заголовке J-Authorization.
Создание временного пользователя
Создает временного пользователя, когда нет доступного действительного токена доступа или обновления. Это позволяет неаутентифицированным пользователям взаимодействовать с API.
HTTP-запрос
POST /users/temp_user_create/
import requests
response = requests.post(HOST+'/users/temp_user_create/')
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"temp_token": "tempYvD9rkf94DrE7R95IXYHBA"
}
Поля ответа
| Field | Type | Description |
|---|---|---|
| temp_token | String | Временный токен аутентификации, действительный в течение 24 часов |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает временный токен |
| 400 | Неверный запрос - Неправильно сформированный запрос или неверный формат ввода |
| 401 | Неавторизован - Неверные учетные данные или требуется аутентификация |
| 429 | Слишком много запросов - Превышен лимит скорости (>10 запросов в минуту с одного IP). Повторите запрос после периода ожидания, указанного в заголовке Retry-After. |
| 500 | Внутренняя ошибка сервера - Сервер столкнулся с непредвиденным условием, попробуйте позже |
Регистрация пользователя
Начало регистрации
Инициирует процесс регистрации пользователя, отправляя код подтверждения на указанный номер телефона.
HTTP-запрос
POST /users/user_send_phone/
import requests
headers = {'J-Authorization': "tempYvD9rkf94DrE7R95IXYHBA"}
data = {"phone_number": "+79162473474"}
response = requests.post(HOST+'/users/user_send_phone/', headers=headers, json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"message": "Call initiated"
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Временный токен, полученный из /users/temp_user_create/ |
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| phone_number | String | Yes | Номер телефона пользователя в международном формате (например, +79162473474) |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли успешно инициирован вызов |
| message | String | Сообщение о статусе процесса отправки кода подтверждения |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Код подтверждения успешно отправлен на указанный номер телефона |
| 400 | Неверный запрос - Неверный формат номера телефона (должен быть в международном формате) или отсутствующий номер телефона |
| 401 | Неавторизован - Недействительный или просроченный временный токен |
| 403 | Запрещено - Доступ запрещен из-за ограничений безопасности |
| 409 | Конфликт - Номер телефона уже зарегистрирован и находится в периоде ожидания (попробуйте снова через 10 минут) |
| 429 | Слишком много запросов - Превышен лимит попыток проверки (максимум 3 попытки за 10 минут). Система блокирует дальнейшие попытки для предотвращения перебора номеров. |
| 500 | Внутренняя ошибка сервера - Не удалось инициировать проверочный вызов, попробуйте позже |
Завершение регистрации
Завершает процесс регистрации, проверяя код, полученный пользователем. Возвращает JWT-токены при успешной проверке.
HTTP-запрос
POST /users/reg_or_login/
import requests
headers = {'J-Authorization': "tempYvD9rkf94DrE7R95IXYHBA"}
data = {"code": 6500}
response = requests.post(HOST+'/users/reg_or_login/', headers=headers, json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTc1NzY4MDY3NywiaWF0IjoxNzI2MTQ0Njc3LCJqdGkiOiIxOWM3YjU1NTBmNjI0MzA2OWIyZTIxMWQ1NWVhY2MyYyIsInVzZXJfaWQiOjR9.y3bhJHXt6U43gX5EO6RwHUBhl1zag80BnppKlyqIJzU",
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Временный токен, полученный из /users/temp_user_create/ |
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | Integer | Yes | Код подтверждения, полученный пользователем (4-6 цифр) |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, была ли проверка успешной |
| data | Object | Содержит токены аутентификации |
| data.refresh | String | Токен обновления с долгосрочной действительностью (30 дней) |
| data.access | String | Токен доступа для запросов API (действителен в течение 24 часов) |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает токены доступа и обновления для аутентифицированного пользователя |
| 400 | Неверный запрос - Неверный формат кода подтверждения (должно быть 4-6 цифр) или отсутствует требуемый код подтверждения |
| 401 | Неавторизован - Код подтверждения неверен или срок его действия истек |
| 403 | Запрещено - Доступ запрещен (номер телефона заблокирован из-за множественных неудачных попыток) |
| 408 | Таймаут запроса - Срок действия сессии подтверждения истек (30 минут с момента отправки кода) |
| 429 | Слишком много запросов - Превышен лимит попыток подтверждения (максимум 5 неправильных вводов кода за 10 минут). IP-адрес может быть временно заблокирован для защиты от автоматизированных атак. |
| 500 | Внутренняя ошибка сервера - Ошибка сервера аутентификации, пожалуйста, повторите процесс регистрации |
Обновление токена
Использует действительный токен обновления для получения нового токена доступа, когда срок действия оригинального токена истек.
HTTP-запрос
POST /users/token/refresh/
import requests
data = {
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTc1NzY4MDY3NywiaWF0IjoxNzI2MTQ0Njc3LCJqdGkiOiI5YmIyMWI5YjVlYmQ0YTllOGUwYjY4ODE5ZWI5YzVhYiIsInVzZXJfaWQiOjR9.M5QEdcZ0J-9t1HcizRDN7Z8-M2kHQUQJjmQFVr9zbvA"
}
response = requests.post(HOST+'/users/token/refresh/', json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTc1NzY4MDY3NywiaWF0IjoxNzI2MTQ0Njc3LCJqdGkiOiI5YmIyMWI5YjVlYmQ0YTllOGUwYjY4ODE5ZWI5YzVhYiIsInVzZXJfaWQiOjR9.M5QEdcZ0J-9t1HcizRDN7Z8-M2kHQUQJjmQFVr9zbvA"
}
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| refresh | String | Yes | Действительный токен обновления, ранее выданный API |
Поля ответа
| Field | Type | Description |
|---|---|---|
| access | String | Новый JWT-токен доступа для аутентификации (действителен в течение ограниченного времени) |
| refresh | String | Новый JWT-токен обновления для использования в будущих обновлениях токена (действителен в течение расширенного периода) |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает новые токены доступа и обновления |
| 400 | Неверный запрос - Отсутствует токен обновления в теле запроса или неправильный формат токена |
| 401 | Неавторизован - Недействительный токен обновления (срок действия истек, отозван или подделан) |
| 403 | Запрещено - Обновление токена не разрешено для этой учетной записи пользователя (учетная запись приостановлена или удалена) |
| 429 | Слишком много запросов - Превышен лимит частоты обновления токена (максимум 10 запросов на обновление в час). Аномальная активность может привести к временной блокировке аккаунта для защиты от компрометации. |
| 500 | Внутренняя ошибка сервера - Временный сбой сервера аутентификации, повторите попытку через несколько минут |
Профиль пользователя
Раздел "Профиль пользователя" предоставляет конечные точки для управления информацией, предпочтениями и настройками учетной записи пользователя. Профили пользователей содержат важную информацию для персонализации, уведомлений и улучшения общего пользовательского опыта в экосистеме Scanderm.
Информация о профиле
Эта конечная точка получает полную информацию о профиле для текущего аутентифицированного пользователя. Ее следует вызывать после успешной аутентификации для персонализации пользовательского опыта в вашем приложении. Возвращаемые данные можно использовать для отображения имени пользователя, аватара и предпочтений во всей вашей интеграции.
Используйте эту конечную точку, когда: - Пользователь впервые входит в ваше приложение - Вам нужно отобразить или проверить информацию о пользователе - Перед сбором новой информации, чтобы проверить, какие данные уже существуют
GET /users/info/
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Этот токен подтверждает личность пользователя и разрешения. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.get(HOST+'/users/info/', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"id": 4,
"username": "test@test.ru",
"phone": "79111231234",
"first_name": "First",
"last_name": "Last",
"birthdate": "1992-01-01",
"gender": 1,
"city": "Санкт-Петербург"
}
}
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным. Всегда проверяйте это поле перед обработкой ответа. |
| data | Object | Полный объект пользователя (см. Поля объекта пользователя). Содержит всю доступную информацию о пользователе, включая личные данные, которые могут быть использованы для персонализации. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает полные данные профиля пользователя. Вся информация о пользователе была успешно получена. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа в заголовке J-Authorization. Токен может быть просрочен, недействителен или не предоставлен. Пользователя следует перенаправить на страницу входа. |
| 403 | Запрещено - Доступ к этому ресурсу запрещен. Это может произойти при попытке доступа к профилю другого пользователя или когда ваше приложение не имеет соответствующих разрешений. |
| 404 | Не найдено - Профиль пользователя не найден. Это может произойти, если учетная запись пользователя была удалена или временно приостановлена администратором. |
| 500 | Внутренняя ошибка сервера - Ошибка базы данных или служба недоступна. Это временная проблема на стороне сервера; повторите запрос после короткой задержки (2-5 секунд). |
| 429 | Слишком много запросов - Превышен лимит запросов к профилю (максимум 60 запросов в час). Частые запросы к профилю могут указывать на автоматизированное сканирование данных и ограничиваются системой безопасности. |
Обновление профиля
Эта конечная точка позволяет обновлять информацию о профиле текущего пользователя. Используйте ее при сборе или изменении пользовательских данных, таких как личные данные, предпочтения или контактная информация. Важно проверять все поля ввода в вашем приложении перед отправкой, чтобы обеспечить правильное форматирование и целостность данных.
Лучшие практики: - Включайте только поля, которые вы хотите обновить - Проверяйте все поля на стороне клиента перед отправкой - Включайте правильную обработку ошибок для сообщений проверки - Обновляйте свой локальный объект пользователя после успешного ответа
PUT /users/info/
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Должен быть действительным и не просроченным. Токен идентифицирует, профиль какого пользователя будет обновлен. |
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| first_name | String | No | Имя пользователя. Используется для персонализированных приветствий и коммуникаций. Должно быть правильно написано с заглавной буквы (например, "John"). |
| last_name | String | No | Фамилия пользователя. Используется для формальных коммуникаций и идентификации учетной записи. Должна быть правильно написана с заглавной буквы (например, "Smith"). |
| birthdate | String | No | Дата рождения пользователя в формате ГГГГ-ММ-ДД (например, "1992-01-01"). Используется для соответствующих возрасту рекомендаций и поздравлений с днем рождения. Должна быть действительной датой, и пользователям должно быть не менее 13 лет. |
| gender | Integer | No | Пол пользователя, представленный в виде числового кода: 1 = мужской, 2 = женский, 0 = не указан/предпочитаю не говорить. Используется для персонализированных рекомендаций и настройки интерфейса. |
| city | String | No | Город проживания пользователя. Используется для рекомендаций на основе местоположения и предложений ближайших магазинов. Должен быть указан на местном языке (например, "Санкт-Петербург" для российских пользователей). |
| username | String | No | Адрес электронной почты пользователя (должен быть в действительном формате электронной почты). Используется как основной идентификатор для входа и для коммуникаций. Должен быть уникальным в системе и правильно отформатированным (например, "user@example.com"). |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
data = {
"first_name": "NewFirst",
"last_name": "NewLast",
"birthdate": "1992-02-15",
"gender": 2,
"city": "Москва"
}
response = requests.put(HOST+'/users/info/', headers=headers, json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"id": 4,
"username": "test@test.ru",
"phone": "79111231234",
"first_name": "NewFirst",
"last_name": "NewLast",
"birthdate": "1992-02-15",
"gender": 2,
"city": "Москва"
}
}
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, было ли обновление профиля успешным. Всегда проверяйте, что это значение true, прежде чем предполагать, что обновление прошло успешно. |
| data | Object | Полный объект пользователя с обновленной информацией (см. Поля объекта пользователя). Содержит весь профиль пользователя со всеми полями, включая недавно обновленные. Сравните с вашими локальными данными для проверки изменений. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Профиль успешно обновлен с предоставленной информацией. Все действительные поля были обновлены в базе данных. |
| 400 | Неверный запрос - Обнаружен неверный формат данных. Это может произойти из-за неправильных форматов даты (должно быть ГГГГ-ММ-ДД), недействительных значений пола (должно быть 0, 1 или 2) или других проблем проверки. Проверьте тело ответа на наличие конкретных сообщений проверки. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа в заголовке J-Authorization. Токен просрочен или недействителен; пользователя следует попросить войти снова. |
| 403 | Запрещено - Доступ к изменению этого ресурса запрещен. Это обычно происходит при попытке изменить профиль другого пользователя или когда вашему приложению не хватает необходимых разрешений. |
| 404 | Не найдено - Пользователь не найден в базе данных. Это может произойти, если учетная запись пользователя была удалена с момента выдачи токена. |
| 422 | Необрабатываемая сущность - Ошибки проверки в предоставленных данных. Это более конкретно, чем 400, и указывает на такие проблемы, как ограничения длины поля (например, имя слишком длинное), недопустимые символы или нарушения уникальных ограничений (например, электронная почта уже используется). |
| 500 | Внутренняя ошибка сервера - Сбой обновления базы данных или служба недоступна. Произошла временная проблема сервера; повторите запрос с экспоненциальной задержкой (начиная с 2 секунд). |
| 429 | Слишком много запросов - Превышен лимит операций обновления профиля (максимум 30 запросов в час). Частые обновления профиля могут указывать на автоматизированную активность и ограничиваются для защиты целостности данных. |
Управление паролем
Конечная точка управления паролем позволяет пользователям безопасно изменять пароль своей учетной записи. Она должна использоваться, когда пользователи хотят усилить свою безопасность или когда они подозревают, что их текущий пароль мог быть скомпрометирован.
Лучшие практики безопасности: - Поощряйте использование надежных паролей (не менее 8 символов с разным регистром, цифрами и символами) - Реализуйте проверку надежности пароля на стороне клиента - Требуйте подтверждения, чтобы избежать опечаток - Не храните пароли в локальном хранилище, куки или переменных сессии
POST /users/change_password/
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Должен быть действительным и не просроченным. Для изменения пароля токен должен быть достаточно новым (менее 30 минут) в качестве дополнительной меры безопасности. |
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| current_password | String | Yes | Текущий пароль пользователя. Это обеспечивает дополнительный уровень безопасности помимо JWT-токена для подтверждения личности пользователя. Должен точно соответствовать сохраненному паролю. |
| new_password | String | Yes | Новый пароль, соответствующий требованиям безопасности: минимум 8 символов, должен включать как минимум одну заглавную букву, одну строчную букву и одну цифру. Специальные символы рекомендуются, но не обязательны. Не может совпадать с любым из последних 5 паролей пользователя. |
| confirm_password | String | Yes | Подтверждение нового пароля. Должно точно соответствовать полю new_password, чтобы предотвратить опечатки и убедиться, что пользователь намеревался установить введенный пароль. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
data = {
"current_password": "OldPassword123",
"new_password": "NewSecurePass456",
"confirm_password": "NewSecurePass456"
}
response = requests.post(HOST+'/users/change_password/', headers=headers, json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"message": "Password successfully updated"
}
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, было ли изменение пароля успешным. Значение true означает, что пароль был обновлен в системе и теперь активен. |
| message | String | Подробное сообщение о статусе операции изменения пароля. Предоставляет удобочитаемое подтверждение, которое может быть отображено пользователю. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Пароль успешно обновлен. Новый пароль теперь активен и должен использоваться для будущих попыток входа. Предыдущие сессии остаются действительными до истечения срока действия их токенов. |
| 400 | Неверный запрос - Пароли не совпадают или новый пароль не соответствует требованиям. Это происходит, когда confirm_password не соответствует new_password или когда пароль не соответствует требованиям к надежности. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа в заголовке J-Authorization или неверный текущий пароль. Это может означать, что токен просрочен или предоставленный current_password не соответствует сохраненному паролю. |
| 403 | Запрещено - Изменение пароля в данный момент не разрешено. Это может произойти, если учетная запись сначала требует подтверждения по электронной почте, если учетная запись заблокирована из-за подозрительной активности или если пароль был недавно изменен (менее 24 часов назад). |
| 422 | Необрабатываемая сущность - Пароль не соответствует требованиям безопасности. Новый пароль может быть слишком похож на старый, содержать имя пользователя, быть часто используемым паролем или не проходить другие проверки безопасности помимо базовой проверки формата. |
| 429 | Слишком много запросов - Слишком много попыток изменения пароля (максимум 5 в час). Это ограничение частоты предотвращает атаки методом перебора. Пользователь должен подождать, прежде чем повторить попытку. |
| 500 | Внутренняя ошибка сервера - Сбой обновления базы данных или служба недоступна. Произошла временная проблема сервера; повторите запрос после короткой задержки. |
Сброс пароля
Эта конечная точка инициирует процесс сброса пароля, отправляя код подтверждения на зарегистрированный адрес электронной почты пользователя. Используйте ее, когда пользователь забыл свой пароль и не может войти обычным способом. Система генерирует безопасный одноразовый код, срок действия которого истекает через 15 минут.
Важные замечания по безопасности: - Этот процесс не требует текущей аутентификации - Пользователь должен подтвердить свою личность с помощью кода, отправленного на его электронную почту - Применяется ограничение скорости для предотвращения атак перечисления - IP-адреса запросов на сброс регистрируются для мониторинга безопасности - Несколько неудачных попыток проверки временно заблокируют учетную запись
POST /users/reset_password_request/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| username | String | Yes | Адрес электронной почты пользователя, зарегистрированный в системе. Должен быть в действительном формате электронной почты (например, "user@example.com"). Для поиска учетной записи используется сравнение без учета регистра. |
import requests
data = {
"username": "user@example.com"
}
response = requests.post(HOST+'/users/reset_password_request/', json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"message": "Reset code sent to email"
}
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос на сброс успешно обработан. Значение true означает, что код сброса был сгенерирован и отправлен по электронной почте. |
| message | String | Подробное сообщение о статусе процесса отправки кода сброса. Предоставляет подтверждение, которое может быть отображено пользователю. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Код сброса отправлен на электронную почту. По соображениям безопасности этот код возвращается, даже если электронная почта не существует в системе (для предотвращения перечисления имен пользователей). Проверьте фактическое поле result, чтобы определить, успешно ли выполнена операция. |
| 400 | Неверный запрос - Неверный формат электронной почты или отсутствует электронная почта. Предоставленное имя пользователя не правильно отформатировано как адрес электронной почты или было пропущено в запросе. |
| 404 | Не найдено - Не найдена учетная запись с предоставленной электронной почтой. Адрес электронной почты не зарегистрирован в системе. Примечание: По соображениям безопасности пользователь не информируется об этом различии в ответе. |
| 429 | Слишком много запросов - Слишком много попыток сброса (максимум 3 в час на IP-адрес). Это ограничение скорости предотвращает атаки методом перебора и перечисления. При многократном нарушении лимита IP-адрес может быть временно заблокирован на срок до 24 часов. |
| 500 | Внутренняя ошибка сервера - Служба электронной почты недоступна или ошибка сервера. Система не смогла отправить электронное письмо для сброса из-за технической проблемы. Попробуйте снова через несколько минут. |
Завершение сброса пароля
Эта конечная точка завершает процесс сброса пароля, проверяя код, полученный по электронной почте, и устанавливая новый пароль. Она должна вызываться после того, как пользователь получит и введет код подтверждения из электронного письма для сброса.
POST /users/reset_password_complete/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| username | String | Yes | Адрес электронной почты пользователя, запросившего сброс пароля. Должен соответствовать электронной почте, куда был отправлен код. |
| code | String | Yes | Код подтверждения, полученный в электронном письме для сброса. 6-значный числовой код, который подтверждает, что пользователь имеет доступ к учетной записи электронной почты. |
| new_password | String | Yes | Новый пароль, соответствующий требованиям безопасности: минимум 8 символов с разным регистром, цифрами и предпочтительно специальными символами. |
| confirm_password | String | Yes | Подтверждение нового пароля. Должно точно соответствовать полю new_password. |
import requests
data = {
"username": "user@example.com",
"code": "123456",
"new_password": "NewSecurePassword123!",
"confirm_password": "NewSecurePassword123!"
}
response = requests.post(HOST+'/users/reset_password_complete/', json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"message": "Password has been reset successfully",
"data": {
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли сброс пароля успешным. |
| message | String | Сообщение о статусе операции сброса пароля. |
| data | Object | Содержит токены аутентификации для немедленного входа после успешного сброса. |
| data.refresh | String | Токен обновления с долгосрочной действительностью (30 дней). |
| data.access | String | Токен доступа для запросов API (действителен в течение 24 часов). |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Пароль был успешно сброшен, и новые токены предоставлены для немедленного входа. |
| 400 | Неверный запрос - Недопустимые или отсутствующие параметры, пароли не совпадают или пароль не соответствует требованиям. |
| 401 | Неавторизован - Неверный код подтверждения или срок его действия истек (действителен только 15 минут). |
| 403 | Запрещено - Учетная запись временно заблокирована из-за слишком большого количества неудачных попыток проверки. |
| 408 | Таймаут запроса - Срок действия сессии сброса истек (30 минут с момента отправки кода). |
| 429 | Слишком много запросов - Слишком много попыток проверки (максимум 5 неправильных кодов). Система может применить прогрессивные задержки между попытками и временную блокировку аккаунта для защиты от автоматизированного подбора кодов. |
| 500 | Внутренняя ошибка сервера - Сбой обновления базы данных или служба недоступна. |
Тестирование
Раздел "Тестирование" предоставляет конечные точки для инициализации, проведения и отправки тестов анализа кожи. Это основная часть сервиса Scanderm, позволяющая пользователям получать персонализированные рекомендации по уходу за кожей на основе анализа лица и ответов на опросник.
Начало нового теста
Инициализация новой сессии теста. Эту конечную точку следует вызывать в начале процесса тестирования перед загрузкой фотографий или отправкой ответов. Она подготавливает систему к получению и обработке данных теста для указанного типа теста.
Когда использовать эту конечную точку: - Перед началом новой сессии анализа - При перезапуске теста с начала - При переключении между различными типами тестов
HTTP-запрос
POST /core/start_new_test/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| test_type | Integer | Yes | Тип теста для начала: |
| - 1 = анализ кожи лица | |||
| - 2 = анализ состояния волос | |||
| - 3 = анализ состояния зубов | |||
| - 4 = анализ состояния языка | |||
| - 5 = анализ ногтей | |||
| Различные типы тестов имеют разные требования к фотографиям и опросникам. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
response = requests.post(HOST+'/core/start_new_test/?test_type=1', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Должен быть действительным и не просроченным. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, была ли сессия теста успешно инициализирована. Значение true означает, что система готова получать данные теста. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Новая сессия теста успешно начата. Переходите к загрузке фото и опроснику. |
| 400 | Неверный запрос - Отсутствуют обязательные параметры или неверное значение test_type. Проверьте, что тип теста поддерживается. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа в заголовке J-Authorization. Пользователь должен правильно аутентифицироваться. |
| 429 | Слишком много запросов - Достигнут лимит сессий тестов (максимум 5 активных тестов в день на пользователя). Завершите или отмените существующие тесты перед началом новых. |
| 500 | Внутренняя ошибка сервера - Служба инициализации теста временно недоступна. Попробуйте снова после короткой задержки. |
Получение вопросов теста
Получение вопросов для текущего теста. Эта конечная точка предоставляет опросник, который пользователи должны заполнить как часть процесса анализа. Вопросы возвращаются в структурированном формате с возможными ответами и логикой навигации.
Вопросы различаются в зависимости от типа теста: - Для анализа кожи лица (test_type=1): вопросы о типе кожи, чувствительности, используемых средствах и т.д. - Для анализа волос (test_type=2): вопросы о типе волос, проблемах кожи головы, используемых средствах - Для анализа зубов (test_type=3): вопросы о гигиене полости рта, проблемах с зубами, чувствительности - Для анализа языка (test_type=4): вопросы о состоянии языка, вкусовых ощущениях, привычках питания - Для анализа ногтей (test_type=5): вопросы о состоянии ногтей, проблемах, регулярности ухода
Когда использовать эту конечную точку: - После успешного начала нового теста - После загрузки и анализа фотографии - Для отображения пользовательского интерфейса опросника пользователю
HTTP-запрос
GET /core/test/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| test_type | Integer | Yes | Тип теста, для которого нужно получить вопросы (1-5). Должен соответствовать test_type, использованному при начале теста. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
response = requests.get(HOST+'/core/test/?test_type=1', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"start_question": 1,
"questions": [
{
"type": "radio",
"text": "Появляется ли на коже в течение дня жирный блеск",
"question_id": 1,
"description": "",
"answers": [
{
"next_question": 2,
"text": "Да",
"comment": "",
"answer_id": 1
},
{
"next_question": 3,
"text": "Нет",
"comment": "",
"answer_id": 2
}
]
},
{
"type": "radio",
"text": "Жирный блеск проявляется в T-зоне или по всему лицу?",
"question_id": 2,
"description": "",
"answers": [
{
"next_question": 5,
"text": "Только в T-зоне",
"comment": "",
"answer_id": 3
},
{
"next_question": 5,
"text": "По всему лицу",
"comment": "",
"answer_id": 4
}
]
}
]
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Должен быть действительным и не просроченным. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным. |
| data | Object | Контейнер для данных опросника. |
| data.start_question | Integer | ID первого вопроса для отображения. Это точка входа для потока опросника. |
| data.questions | Array | Список всех вопросов в опроснике. |
| data.questions[].type | String | Тип вопроса (например, "radio", "checkbox", "select"). Определяет, как вопрос должен отображаться. |
| data.questions[].text | String | Текст вопроса для отображения пользователю. |
| data.questions[].question_id | Integer | Уникальный идентификатор вопроса. Используется при отправке ответов. |
| data.questions[].description | String | Дополнительное описание или текст помощи для вопроса (может быть пустым). |
| data.questions[].answers | Array | Список возможных ответов на этот вопрос. |
| data.questions[].answers[].next_question | Integer | ID следующего вопроса для отображения, если выбран этот ответ. Определяет поток опросника. |
| data.questions[].answers[].text | String | Текст ответа для отображения пользователю. |
| data.questions[].answers[].comment | String | Дополнительная информация об этом варианте ответа (может быть пустой). |
| data.questions[].answers[].answer_id | Integer | Уникальный идентификатор этого ответа. Используется при отправке ответов. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает вопросы теста в правильной последовательности. |
| 400 | Неверный запрос - Отсутствуют обязательные параметры или неверное значение test_type. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа в заголовке J-Authorization. |
| 404 | Не найдено - Не найдена активная сессия теста для этого test_type. Сначала вы должны вызвать start_new_test. |
| 500 | Внутренняя ошибка сервера - Служба опросника временно недоступна. |
Отправка фотографии для анализа
Загрузка фотографии для анализа с использованием алгоритмов компьютерного зрения. Эта конечная точка принимает закодированное в base64 изображение и обрабатывает его для оценки состояния в зависимости от выбранного типа теста.
Важные рекомендации по фотографии в зависимости от типа теста:
Для анализа лица (test_type=1):
- Фотография должна четко показывать лицо пользователя при хорошем освещении
- Лицо должно быть в центре и занимать существенную часть изображения
- Не должны применяться фильтры, макияж или цифровые улучшения
Для анализа волос (test_type=2):
- Волосы должны быть сухими и распущенными
- Фотография должна показывать волосы и кожу головы
- Желательно сделать несколько снимков: макушка головы, затылок и виски
Для анализа зубов (test_type=3):
- Фотография должна четко показывать переднюю часть зубов при улыбке
- Освещение должно быть ярким и равномерным
- Лицо должно быть расположено прямо перед камерой
Для анализа языка (test_type=4):
- Язык должен быть виден полностью при открытом рте
- Освещение должно быть ярким для отображения текстуры и цвета языка
- Фотография должна быть сделана без фильтров
Для анализа ногтей (test_type=5):
- Руки должны быть чистыми, без лака на ногтях
- Фотография должна четко показывать ногтевую пластину с хорошим освещением
- Необходимо сфотографировать все пальцы хотя бы одной руки
HTTP-запрос
POST /core/test_photo/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| test_type | Integer | Yes | Тип теста, связанного с фотографией (1-5). Должен соответствовать test_type, использованному при начале теста. |
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| photo | String | Yes | Фотография, закодированная в base64. Должна быть в формате JPEG или PNG с максимальным размером 5 МБ. |
import requests
import base64
# Чтение и кодирование изображения
with open("face_photo.jpg", "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
data = {'photo': encoded_string}
response = requests.post(HOST+'/core/test_photo/?test_type=1', headers=headers, json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом для анализа лица (test_type=1):
{
"result": true,
"data": {
"face_rank": 9.2,
"age": 31,
"face_conds": {
"Атрофия кожи": 0,
"Жирный блеск": 15,
"Комедоны": 0,
"Круги/мешки под глазами": 25,
"Купероз (телеангиэктазии)": 0,
"Морщины": 15,
"Папулы и пустулы при акне": 0,
"Пигментация": 5,
"Постакне": 0,
"Расширенные поры": 30,
"Розацеа (покраснение щек)": 5,
"Рубцы": 10,
"Шелушение": 5
},
"analyzed_photo_url": "https://storage.yandexcloud.net/bsmain/user_photos/analyzed_42561789.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=7a4c8b1e0f5d2a36b9e7c482d1f5a09e3b8c7d6f5a4b3c2d1e0f9a8b7c6d5e4f"
}
}
Для анализа волос (test_type=2) ответ имеет следующий вид:
{
"result": true,
"data": {
"hair_rank": 8.3,
"hair_conds": {
"Секущиеся кончики": 35,
"Повышенная жирность": 10,
"Ломкость": 15,
"Выпадение": 20,
"Тусклость": 30,
"Сухость": 5,
"Перхоть": 0
},
"hair_type": "Смешанный",
"hair_porosity": "Средняя",
"analyzed_photo_url": "https://storage.yandexcloud.net/bsmain/user_photos/hair_analyzed_42561790.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=8b7c6d5e4f3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a"
}
}
Для анализа зубов (test_type=3) ответ имеет следующий вид:
{
"result": true,
"data": {
"teeth_rank": 7.5,
"teeth_conds": {
"Налет": 40,
"Изменение цвета": 25,
"Кариес": 0,
"Зубной камень": 15,
"Воспаление десен": 10,
"Чувствительность": 35
},
"teeth_color": "A3",
"analyzed_photo_url": "https://storage.yandexcloud.net/bsmain/user_photos/teeth_analyzed_42561791.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=5e4f3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3"
}
}
Для анализа языка (test_type=4) ответ имеет следующий вид:
{
"result": true,
"data": {
"tongue_rank": 6.8,
"tongue_conds": {
"Налет": 30,
"Трещины": 15,
"Отек": 0,
"Изменение цвета": 25,
"Отпечатки зубов": 40,
"Сухость": 20
},
"tongue_color": "Бледно-розовый с белым налетом",
"analyzed_photo_url": "https://storage.yandexcloud.net/bsmain/user_photos/tongue_analyzed_42561792.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=1e0f9a8b7c6d5e4f3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9"
}
}
Для анализа ногтей (test_type=5) ответ имеет следующий вид:
{
"result": true,
"data": {
"nails_rank": 8.7,
"nails_conds": {
"Ломкость": 15,
"Расслоение": 25,
"Бороздки": 10,
"Пятна": 5,
"Кутикула": 20,
"Форма": 0
},
"nails_type": "Нормальные",
"analyzed_photo_url": "https://storage.yandexcloud.net/bsmain/user_photos/nails_analyzed_42561793.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c"
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Должен быть действительным и не просроченным. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, была ли фотография успешно проанализирована. |
| data | Object | Контейнер для результатов анализа. |
| data.face_rank | Float | Общая оценка здоровья кожи по шкале от 1.0 до 10.0. Более высокие значения указывают на лучшее состояние кожи. |
| data.age | Integer | Предполагаемый возраст на основе черт лица и состояния кожи. Может отличаться от фактического возраста пользователя. |
| data.face_conds | Object | Карта обнаруженных состояний кожи с процентами тяжести (0-100). Более высокие значения указывают на более серьезные состояния. |
| data.analyzed_photo_url | String | Защищенный URL на проанализированную фотографию с отмеченными областями проблем. Срок действия этого URL истекает через 1 час. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Фотография успешно проанализирована. Результаты доступны в ответе. |
| 400 | Неверный запрос - Неверный формат фотографии, отсутствующие параметры или нет активной сессии теста. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа в заголовке J-Authorization. |
| 413 | Слишком большая нагрузка - Файл изображения превышает максимальный размер в 5 МБ. |
| 422 | Необрабатываемая сущность - На фото не обнаружено лицо, или лицо слишком маленькое/нечеткое для анализа. |
| 429 | Слишком много запросов - Превышен лимит загрузки фотографий (максимум 3 попытки на тест). Система защиты отслеживает как успешные, так и неудачные попытки загрузки для предотвращения чрезмерной нагрузки на систему анализа изображений. |
| 500 | Внутренняя ошибка сервера - Служба анализа фотографий временно недоступна или ошибка обработки. |
Отправка ответов на тест
Отправка ответов пользователя на вопросы теста. Эта конечная точка отправляет заполненные ответы опросника для обработки вместе с анализом фотографии, которые вместе сгенерируют персонализированные рекомендации в соответствии с типом проведенного теста.
Когда использовать эту конечную точку: - После того, как пользователь заполнил все необходимые вопросы в опроснике - После успешной загрузки и анализа фотографии - В качестве последнего шага перед получением результатов теста
Обратите внимание, что структура ответов должна соответствовать типу теста: - Для анализа кожи лица (test_type=1): ответы о типе кожи, чувствительности, проблемах - Для анализа волос (test_type=2): ответы о типе волос и проблемах - Для анализа зубов (test_type=3): ответы о гигиене полости рта и проблемах - Для анализа языка (test_type=4): ответы о состоянии языка и симптомах - Для анализа ногтей (test_type=5): ответы о состоянии и проблемах ногтей
HTTP-запрос
POST /core/test/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| test_type | Integer | Yes | Тип теста, для которого нужно отправить ответы (1-5). Должен соответствовать test_type, использованному при начале теста. |
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| data | Array | Yes | Список пар вопрос/ответ, представляющих ответы пользователя на опросник. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
data = {
"data": [
{
"question_id": 1,
"answer_id": 1
},
{
"question_id": 2,
"answer_id": 3
},
{
"question_id": 5,
"answer_id": 11
},
{
"question_id": 6,
"answer_id": 14
},
{
"question_id": 7,
"answer_id": 22
}
]
}
response = requests.post(HOST+'/core/test/?test_type=1', headers=headers, json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Должен быть действительным и не просроченным. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, были ли ответы на тест успешно отправлены и обработаны. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Ответы на тест отправлены и обработаны успешно. Результаты теперь доступны. |
| 400 | Неверный запрос - Недействительные или отсутствующие ответы, неполный опросник или нет активной сессии теста. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа в заголовке J-Authorization. |
| 404 | Не найдено - Не найдена активная сессия теста или упомянутые вопросы/ответы не существуют. |
| 422 | Необрабатываемая сущность - Необходимый анализ фотографии не завершен перед отправкой ответов. |
| 500 | Внутренняя ошибка сервера - Служба обработки ответов временно недоступна или ошибка обработки. |
Магазины
Раздел "Магазины" предоставляет конечные точки для поиска, просмотра и выбора магазинов, где доступны продукты, рекомендованные после тестирования кожи. Это важная часть процесса, поскольку она соединяет результаты анализа кожи с фактическими продуктами, доступными для покупки.
Список магазинов
Получение списка всех доступных магазинов. Эта конечная точка предоставляет постраничный список магазинов, который можно фильтровать по городу, типу теста или близости к координатам.
Когда использовать эту конечную точку: - При отображении пользователю списка ближайших магазинов - Для поиска магазинов в определенном городе - При фильтрации магазинов, поддерживающих конкретный тип тестирования - Для построения карты магазинов вокруг местоположения пользователя
HTTP-запрос
GET /shop/shop_list/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| test_type | Integer | Yes | Тип теста, для которого нужно отфильтровать магазины. Определяет, какие магазины поддерживают конкретный тип анализа кожи. |
| city | String | No | Фильтрация магазинов по названию города. Полезно, когда пользователь хочет найти магазины в конкретном городе. |
| page | Integer | No | Номер страницы для пагинации (по умолчанию: 1). Используйте, когда общее количество магазинов превышает размер страницы. |
| page_size | Integer | No | Количество магазинов на странице (по умолчанию: 20, максимум: 100). Оптимизируйте в зависимости от требований пользовательского интерфейса. |
| latitude | Float | No | Широта местоположения пользователя для поиска по близости. Требуется вместе с longitude для поиска ближайших магазинов. |
| longitude | Float | No | Долгота местоположения пользователя для поиска по близости. Требуется вместе с latitude для поиска ближайших магазинов. |
| max_distance | Integer | No | Максимальное расстояние в километрах для поиска по близости. Ограничивает результаты заданным радиусом от указанной точки. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.get(HOST+'/shop/shop_list/?test_type=1&city=Москва', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"shops": [
{
"id": 937719,
"city": "Москва",
"address": "Москва, Серпуховский Вал ул, 6",
"worktime": "10:00 - 22:00",
"description": "",
"point": "55.712208, 37.618048",
"test_type": 1
},
{
"id": 243612,
"city": "Санкт-Петербург",
"address": "Санкт-Петербург, Невский пр-кт, 105, литера А",
"worktime": "10:00 - 22:00",
"description": "",
"point": "59.929425, 30.368482",
"test_type": 1
}
],
"pagination": {
"total_items": 128,
"total_pages": 7,
"current_page": 1,
"page_size": 20
}
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа. Используется для идентификации пользователя и доступа к данным магазинов. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным. Проверьте этот флаг перед обработкой данных. |
| data | Object | Контейнер для данных ответа. Содержит список магазинов и информацию о пагинации. |
| data.shops | Array | Список объектов магазинов. Каждый объект содержит базовую информацию о магазине. |
| data.shops[].id | Integer | Уникальный идентификатор магазина. Используется при выборе магазина для теста. |
| data.shops[].city | String | Город, где находится магазин. Полезно для группировки магазинов по местоположению. |
| data.shops[].address | String | Полный адрес магазина. Отображается пользователям для физического посещения. |
| data.shops[].worktime | String | Часы работы магазина. Важно для планирования посещения. |
| data.shops[].description | String | Описание магазина (если доступно). Предоставляет дополнительную информацию о магазине. |
| data.shops[].point | String | Географические координаты (широта, долгота). Используются для отображения на карте. |
| data.shops[].test_type | Integer | Тип тестов, доступных в этом магазине. Гарантирует совместимость с текущим тестом. |
| data.pagination | Object | Информация о пагинации. Используется для навигации по большим наборам результатов. |
| data.pagination.total_items | Integer | Общее количество магазинов, соответствующих критериям. Полезно для отображения прогресса пользователю. |
| data.pagination.total_pages | Integer | Общее количество страниц. Используется для создания элементов пагинации. |
| data.pagination.current_page | Integer | Текущий номер страницы. Указывает на текущее положение в наборе результатов. |
| data.pagination.page_size | Integer | Количество элементов на странице. Определяет, сколько магазинов отображается за раз. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает список магазинов в соответствии с указанными параметрами фильтрации. |
| 400 | Неверный запрос - Отсутствуют обязательные параметры или параметры имеют неверный формат. Проверьте, что test_type указан корректно. |
| 401 | Неавторизован - Недействительный или отсутствующий токен в заголовке J-Authorization. Пользователь должен аутентифицироваться заново. |
| 429 | Слишком много запросов - Превышен лимит запросов к списку магазинов (максимум 120 запросов в час). Частые запросы к каталогу магазинов могут указывать на автоматизированное сканирование и ограничиваются для защиты API. |
| 500 | Внутренняя ошибка сервера - Временный сбой в работе сервиса каталога магазинов. Повторите запрос позже. |
Детали магазина
Получение подробной информации о конкретном магазине. Эта конечная точка предоставляет расширенные сведения о выбранном магазине, включая доступные функции, количество продуктов и изображения.
Когда использовать эту конечную точку: - После выбора магазина из списка для отображения подробной информации - Перед выбором магазина для рекомендаций продуктов - При отображении страницы с детальной информацией о магазине - Для проверки доступности продуктов в конкретном магазине
HTTP-запрос
GET /shop/shop/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| shop_id | Integer | Yes | ID магазина для получения информации. Должен соответствовать действительному магазину из списка. |
| test_type | Integer | Yes | Тип теста, связанного с этим магазином. Обеспечивает совместимость с текущим тестом. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.get(HOST+'/shop/shop/?shop_id=937719&test_type=1', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"id": 937719,
"city": "Москва",
"address": "Москва, Серпуховский Вал ул, 6",
"worktime": "10:00 - 22:00",
"description": "",
"point": "55.712208, 37.618048",
"test_type": 1,
"available_products_count": 856,
"features": ["parking", "wifi", "consultant"],
"images": [
"https://storage.yandexcloud.net/bsmain/media/shops/937719_1.jpeg",
"https://storage.yandexcloud.net/bsmain/media/shops/937719_2.jpeg"
]
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа. Необходим для аутентификации и доступа к данным магазина. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным. Проверьте перед обработкой данных. |
| data | Object | Подробная информация о магазине. Содержит все доступные сведения о выбранном магазине. |
| data.id | Integer | Уникальный идентификатор магазина. Используется для дальнейших операций с этим магазином. |
| data.city | String | Город, где находится магазин. Помогает пользователям ориентироваться географически. |
| data.address | String | Полный адрес магазина. Необходим для физического посещения. |
| data.worktime | String | Часы работы магазина. Важно для планирования визита. |
| data.description | String | Описание магазина. Содержит дополнительную информацию о магазине. |
| data.point | String | Географические координаты (широта, долгота). Используются для отображения на карте. |
| data.test_type | Integer | Тип тестов, доступных в этом магазине. Подтверждает совместимость с текущим тестом. |
| data.available_products_count | Integer | Количество продуктов, доступных в этом магазине. Индикатор разнообразия доступных товаров. |
| data.features | Array | Список доступных функций в этом магазине. Может включать такие удобства как парковка, Wi-Fi, консультанты. |
| data.images | Array | URL-адреса изображений магазина (если доступны). Помогают пользователям визуально ознакомиться с магазином. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает подробную информацию о магазине. Все запрошенные данные успешно получены. |
| 400 | Неверный запрос - Отсутствуют обязательные параметры или они имеют неверный формат. Проверьте правильность указания shop_id и test_type. |
| 401 | Неавторизован - Недействительный или отсутствующий токен в заголовке J-Authorization. Требуется повторная аутентификация. |
| 404 | Не найдено - Магазин не найден с указанным shop_id или test_type не поддерживается в этом магазине. |
| 429 | Слишком много запросов - Превышен лимит запросов детальной информации о магазинах (максимум 300 запросов в час). Частые повторяющиеся запросы могут указывать на автоматизированное сканирование. |
| 500 | Внутренняя ошибка сервера - Временная проблема при получении данных магазина. Повторите запрос позже. |
Выбор магазина
Выбор магазина для рекомендаций продуктов. Эту конечную точку необходимо вызвать после начала нового теста и перед отправкой результатов теста. Выбор магазина критически важен, поскольку рекомендации продуктов основаны на доступных запасах в указанном магазине.
Важные примечания к процессу работы:
- Эту конечную точку необходимо вызвать после начала нового теста с помощью конечной точки start_new_test
- Выбор магазина влияет на то, какие продукты будут рекомендованы на основе местных запасов
- Один и тот же тест может быть связан с разными магазинами, чтобы увидеть различные рекомендации продуктов
- Выбор магазина должен быть подтвержден перед продолжением отправки теста
HTTP-запрос
POST /shop/shop/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| shop_id | String | Yes | ID магазина для выбора рекомендаций продуктов. Должен быть действительным ID магазина, поддерживающим выбранный тип теста. |
| test_type | Integer | Yes | Тип теста, связанного с этим выбором магазина. Должен соответствовать типу теста ранее начатого теста. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
data = {"shop_id": "138440"}
response = requests.post(HOST+'/shop/shop/?test_type=1', headers=headers, json=data)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"id": 138440,
"city": "Санкт-Петербург",
"address": "Санкт-Петербург, Комендантский пр-кт, 30, корпус 1, литера А",
"worktime": "10:00 - 22:00",
"description": "",
"point": "60.015125, 30.249465",
"test_type": 1
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Должен быть действительным и не просроченным. Временные токены не принимаются для выбора магазина. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли выбор магазина успешным. Значение true означает, что магазин был связан с текущим тестом. |
| data | Object | Упрощенный объект магазина (см. Поля объекта магазина), содержащий основные детали выбранного магазина. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Магазин успешно выбран и связан с текущим тестом. Рекомендации продуктов будут основаны на запасах этого магазина. |
| 400 | Неверный запрос - Отсутствуют обязательные параметры (shop_id или test_type) или не найден активный тест. Вы должны начать тест перед выбором магазина. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа в заголовке J-Authorization. Пользователю требуется надлежащая аутентификация. |
| 403 | Запрещено - У пользователя нет разрешения на выбор этого магазина, или тест находится в неправильном состоянии для выбора магазина. |
| 404 | Не найдено - Магазин не найден с предоставленным shop_id, или указанный test_type не поддерживается в этом магазине. |
| 409 | Конфликт - Для этого теста уже выбран другой магазин, и его нельзя изменить на текущем этапе теста. |
| 429 | Слишком много запросов - Превышен лимит запросов выбора магазина (максимум 30 запросов в час). Частая смена магазинов может указывать на автоматизированные действия и ограничивается для защиты целостности данных тестирования. |
| 500 | Внутренняя ошибка сервера - Служба выбора магазина временно недоступна или ошибка базы данных. |
Корзина покупок
Раздел "Корзина покупок" предоставляет конечные точки для управления корзиной покупок пользователя, включая просмотр текущей корзины, добавление продуктов в корзину и удаление продуктов из корзины.
Получение корзины
Получение текущей корзины покупок пользователя. Эта конечная точка возвращает все продукты, добавленные в корзину, общую стоимость и информацию о магазине. При использовании любого типа теста с общей корзиной (test_type="all") будет возвращена общая корзина, не привязанная к конкретному тесту.
Когда использовать эту конечную точку:
- При открытии страницы корзины в приложении
- После добавления или удаления продукта для обновления информации
- Перед оформлением заказа для проверки содержимого
- Для получения общей корзины при работе с test_type="all"
HTTP-запрос
GET /shop/basket/
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.get(HOST+'/shop/basket/', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"products": [
{
"price": 69.98,
"quantity": 9,
"product": 331,
"shop": 182,
"code": "1000273642",
"brand": "laf",
"price_segment": 2,
"priority": 2,
"img": "https://storage.yandexcloud.net/bsmain/media/products/1000273642.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=ac259a93093158fa68cbdadd1357f203a964f32ef36ec96c7929887e4edb1e08",
"value": "",
"country": "",
"category": 1,
"stage": 32,
"description": "В составе маски высокоэффективные компоненты: гиалуроновая кислота, водорастворимый хитозан и провитамин В5 глубоко увлажняют, разглаживают и тонизирует кожу. Водоросли замедляют процессы старения, а также моделируют овал лица. ",
"name": "LAF Маска для лица Глубокое увлажнение с гиалуроновой кислотой 2х7мл"
}
],
"created_at": "2024-09-12T15:40:40.738074Z",
"order_num": 51785,
"total_items": 9,
"total_price": 629.82,
"shop": {
"id": 138440,
"city": "Санкт-Петербург",
"address": "Санкт-Петербург, Комендантский пр-кт, 30, корпус 1, литера А",
"worktime": "10:00 - 22:00",
"description": "",
"point": "60.015125, 30.249465",
"test_type": 1
}
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа. Используется для идентификации пользователя и доступа к его корзине. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным. Всегда проверяйте это поле перед обработкой данных. |
| data | Object | Информация о корзине. Содержит все детали о содержимом корзины и связанных элементах. |
| data.products | Array | Список продуктов в корзине. Каждый элемент представляет отдельный продукт с количеством. |
| data.created_at | String | Временная метка создания или последнего обновления корзины. Формат ISO 8601. |
| data.order_num | Integer | Уникальный идентификатор корзины/заказа. Используется для отслеживания и ссылок. |
| data.total_items | Integer | Общее количество товаров в корзине. Сумма количеств всех продуктов. |
| data.total_price | Float | Общая стоимость всех товаров в корзине. Учитывает цену и количество каждого продукта. |
| data.shop | Object | Информация о магазине, связанном с этой корзиной. Подробности о физическом местоположении магазина. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает содержимое корзины. Корзина может быть пустой, но запрос выполнен успешно. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа. Пользователь должен аутентифицироваться. |
| 404 | Не найдено - Активная корзина не найдена. Пользователь еще не создал корзину или она была очищена. |
| 429 | Слишком много запросов - Превышен лимит запросов к корзине (максимум 120 запросов в час). Частые запросы к корзине могут указывать на автоматизированное сканирование и ограничиваются системой безопасности. |
| 500 | Внутренняя ошибка сервера - Временный сбой в работе сервиса корзины. Повторите запрос после короткой задержки. |
Добавление продукта в корзину
Добавление продукта в корзину покупок. Эта конечная точка позволяет пользователям добавлять выбранные продукты в корзину для последующей покупки. Поддерживает работу как с корзинами, привязанными к конкретному типу теста, так и с общей корзиной.
Когда использовать эту конечную точку: - Когда пользователь нажимает кнопку "Добавить в корзину" на странице продукта - При увеличении количества существующего продукта в корзине - При добавлении рекомендованных продуктов из результатов теста - Для добавления товаров в общую корзину при использовании test_type="all"
HTTP-запрос
PUT /shop/basket/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| product_code | String | Yes | Код продукта для добавления в корзину. Должен соответствовать действительному продукту в системе. |
| test_type | String | Yes | Тип теста, связанного с этой корзиной. Возможные значения: "1", "2", "3", "4", "5", "all". При значении "all" товар добавляется в общую корзину, не привязанную к конкретному типу теста. |
| count | Integer | Yes | Количество продукта для добавления. Должно быть положительным целым числом. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
# Добавление конкретного продукта в корзину типа теста 1
response = requests.put(HOST+'/shop/basket/?product_code=1000273642&test_type=1&count=9', headers=headers)
# Добавление продукта в общую корзину
response = requests.put(HOST+'/shop/basket/?product_code=1000273642&test_type=all&count=1', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа. Необходим для идентификации пользователя и его корзины. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, была ли операция добавления продукта успешной. Значение true означает, что продукт был успешно добавлен или обновлен в корзине. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Продукт добавлен в корзину. Операция выполнена успешно, и продукт теперь находится в корзине пользователя. |
| 400 | Неверный запрос - Отсутствуют обязательные параметры или они имеют неверный формат. Проверьте правильность указания product_code, test_type и count. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа. Пользователь должен аутентифицироваться, чтобы добавить продукты в корзину. |
| 404 | Не найдено - Продукт не найден с указанным кодом. Проверьте правильность product_code. |
| 422 | Необрабатываемая сущность - Недопустимое количество или продукт недоступен. Возможно, запрошенное количество превышает доступное в магазине. |
| 429 | Слишком много запросов - Превышен лимит операций с корзиной (максимум 60 запросов в час). Частые добавления и удаления могут указывать на автоматизированную активность. |
| 500 | Внутренняя ошибка сервера - Временный сбой в работе сервиса корзины. Попробуйте повторить запрос позже. |
Удаление продукта из корзины
Удаление продукта из корзины покупок. Эта конечная точка позволяет пользователям удалять ранее добавленные продукты из своей корзины.
Когда использовать эту конечную точку: - Когда пользователь нажимает кнопку "Удалить" рядом с продуктом в корзине - При очистке корзины для добавления новых продуктов - Когда пользователь решает не покупать ранее выбранный продукт
HTTP-запрос
DELETE /shop/basket/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| product_code | String | Yes | Код продукта для удаления из корзины. Должен соответствовать продукту, который уже находится в корзине. |
| test_type | String | Yes | Тип теста, связанного с этой корзиной. Возможные значения: "1", "2", "3", "4", "5", "all". При значении "all" работает с общей корзиной. |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.delete(HOST+'/shop/basket/?product_code=1000273642&test_type=1', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа. Необходим для идентификации пользователя и его корзины. |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, была ли операция удаления продукта успешной. Значение true означает, что продукт был успешно удален из корзины. |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Продукт удален из корзины. Операция выполнена успешно, и продукт больше не находится в корзине пользователя. |
| 400 | Неверный запрос - Отсутствуют обязательные параметры или они имеют неверный формат. Проверьте правильность указания product_code и test_type. |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа. Пользователь должен аутентифицироваться для выполнения операций с корзиной. |
| 404 | Не найдено - Продукт не найден в корзине. Возможно, продукт уже был удален или никогда не добавлялся в корзину. |
| 429 | Слишком много запросов - Превышен лимит операций с корзиной (максимум 60 запросов в час). Частые операции удаления могут быть признаком автоматизированной активности. |
| 500 | Внутренняя ошибка сервера - Временный сбой в работе сервиса корзины. Попробуйте повторить запрос позже. |
Продукты
Список продуктов
Получение постраничного списка продуктов, доступных в конкретном магазине. Эта конечная точка поддерживает фильтрацию по различным параметрам.
HTTP-запрос
GET /shop/products/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| shop_id | Integer | Yes | ID магазина, из которого нужно получить продукты |
| test_type | Integer | Yes | Тип теста, связанного с этими продуктами |
| category | Integer | No | Фильтр по ID категории продукта |
| brand | String | No | Фильтр по названию бренда |
| price_min | Float | No | Минимальный фильтр цены |
| price_max | Float | No | Максимальный фильтр цены |
| stage | Integer | No | Фильтр по ID этапа ухода |
| page | Integer | No | Номер страницы для пагинации (по умолчанию: 1) |
| page_size | Integer | No | Количество продуктов на странице (по умолчанию: 20, максимум: 50) |
| sort_by | String | No | Поле сортировки (варианты: price, name, popularity) |
| sort_order | String | No | Направление сортировки (варианты: asc, desc) |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.get(HOST+'/shop/products/?shop_id=138440&test_type=1&category=1&page=1&page_size=10', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"products": [
{
"id": 331,
"code": "1000273642",
"name": "LAF Маска для лица Глубокое увлажнение с гиалуроновой кислотой 2х7мл",
"brand": "laf",
"price": 69.98,
"category": 1,
"stage": 32,
"price_segment": 2,
"img": "https://storage.yandexcloud.net/bsmain/media/products/1000273642.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=ac259a93093158fa68cbdadd1357f203a964f32ef36ec96c7929887e4edb1e08",
"value": "2x7мл",
"priority": 2,
"in_stock": true
},
{
"id": 204,
"code": "1000211076",
"name": "LIBREDERM Гиалуроновый крем Ночной гидробаланс 50мл",
"brand": "librederm",
"price": 1149.99,
"category": 1,
"stage": 2,
"price_segment": 2,
"img": "https://storage.yandexcloud.net/bsmain/media/products/1000211076.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T155210Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=9de0b839f7f4131da2aa5e68a691aba4e26fb6bffddf87dbe3bad4b4781bdc65",
"value": "50мл",
"priority": 2,
"in_stock": true
}
],
"pagination": {
"total_items": 856,
"total_pages": 86,
"current_page": 1,
"page_size": 10
},
"filters": {
"categories": [
{"id": 1, "name": "Уход за лицом", "count": 450},
{"id": 2, "name": "Очищение", "count": 120},
{"id": 3, "name": "Увлажнение и питание", "count": 186}
],
"brands": [
{"name": "librederm", "count": 42},
{"name": "laf", "count": 15},
{"name": "nivea", "count": 58}
],
"price_range": {
"min": 49.99,
"max": 5999.00
},
"stages": [
{"id": 1, "name": "Дневной крем", "count": 35},
{"id": 2, "name": "Ночной крем", "count": 28},
{"id": 11, "name": "Сыворотка", "count": 42},
{"id": 32, "name": "Маска", "count": 63}
]
}
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным |
| data | Object | Контейнер для данных ответа |
| data.products | Array | Список объектов продуктов |
| data.products[].id | Integer | Уникальный идентификатор продукта |
| data.products[].code | String | Код/артикул продукта |
| data.products[].name | String | Название продукта |
| data.products[].brand | String | Название бренда (в нижнем регистре) |
| data.products[].price | Float | Цена продукта |
| data.products[].category | Integer | ID категории продукта |
| data.products[].stage | Integer | ID этапа ухода |
| data.products[].price_segment | Integer | Ценовой сегмент (1=бюджетный, 2=средний, 3=премиум) |
| data.products[].img | String | URL на изображение продукта |
| data.products[].value | String | Объем/вес продукта |
| data.products[].priority | Integer | Приоритет продукта/уровень рекомендации |
| data.products[].in_stock | Boolean | Статус наличия |
| data.pagination | Object | Информация о пагинации |
| data.filters | Object | Доступные варианты фильтров |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает список продуктов |
| 400 | Неверный запрос - Отсутствуют обязательные параметры |
| 401 | Неавторизован - Недействительный или отсутствующий токен |
| 404 | Не найдено - Магазин не найден |
Получение деталей продукта
Получение подробной информации о конкретном продукте.
HTTP-запрос
GET /shop/product/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| product_code | String | Yes | Код продукта, для которого нужно получить подробную информацию |
| shop_id | Integer | Yes | ID магазина, где доступен продукт |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.get(HOST+'/shop/product/?product_code=1000273642&shop_id=138440', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"id": 331,
"code": "1000273642",
"name": "LAF Маска для лица Глубокое увлажнение с гиалуроновой кислотой 2х7мл",
"brand": "laf",
"price": 69.98,
"category": 1,
"stage": 32,
"price_segment": 2,
"priority": 2,
"img": "https://storage.yandexcloud.net/bsmain/media/products/1000273642.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=ac259a93093158fa68cbdadd1357f203a964f32ef36ec96c7929887e4edb1e08",
"value": "2x7мл",
"country": "Россия",
"description": "В составе маски высокоэффективные компоненты: гиалуроновая кислота, водорастворимый хитозан и провитамин В5 глубоко увлажняют, разглаживают и тонизирует кожу. Водоросли замедляют процессы старения, а также моделируют овал лица.",
"effect": "Увлажнение, разглаживание, тонизирование кожи, замедление процессов старения",
"how_to_use": "Нанесите на очищенную кожу лица, избегая области вокруг глаз, оставьте на 15-20 минут, затем смойте теплой водой.",
"spec": "Aqua, Glycerin, Panthenol, Chitosan, Sodium Hyaluronate, Laminaria Digitata Extract, Phenoxyethanol, Ethylhexylglycerin, Parfum, Citric Acid",
"components": [
{
"name": "гиалуроновая кислота",
"description": "sodium hyaluronate"
},
{
"name": "провитамин В5",
"description": "panthenol"
},
{
"name": "хитозан",
"description": "chitosan"
}
],
"in_stock": true,
"quantity": 25,
"confirmation_level": 0.87,
"similar_products": [
{
"id": 332,
"code": "1000275123",
"name": "NIVEA Маска для лица Увлажняющая 2х7.5мл",
"brand": "nivea",
"price": 89.99,
"img": "https://storage.yandexcloud.net/bsmain/media/products/1000275123.jpeg"
}
]
}
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным |
| data | Object | Подробная информация о продукте |
| data.id | Integer | Уникальный идентификатор продукта |
| data.code | String | Код/артикул продукта |
| data.name | String | Название продукта |
| data.brand | String | Название бренда (в нижнем регистре) |
| data.price | Float | Цена продукта |
| data.category | Integer | ID категории продукта |
| data.stage | Integer | ID этапа ухода |
| data.price_segment | Integer | Ценовой сегмент (1=бюджетный, 2=средний, 3=премиум) |
| data.priority | Integer | Приоритет продукта/уровень рекомендации |
| data.img | String | URL на изображение продукта |
| data.value | String | Объем/вес продукта |
| data.country | String | Страна происхождения |
| data.description | String | Подробное описание продукта |
| data.effect | String | Эффекты/преимущества продукта |
| data.how_to_use | String | Инструкции по использованию |
| data.spec | String | Ингредиенты продукта |
| data.components | Array | Ключевые активные ингредиенты |
| data.in_stock | Boolean | Статус наличия |
| data.quantity | Integer | Доступное количество |
| data.confirmation_level | Float | Оценка уверенности рекомендации (0-1) |
| data.similar_products | Array | Список похожих продуктов |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает подробную информацию о продукте |
| 400 | Неверный запрос - Отсутствуют обязательные параметры |
| 401 | Неавторизован - Недействительный или отсутствующий токен |
| 404 | Не найдено - Продукт не найден |
Результаты
Результаты теста (продукты)
Retrieve the complete test results including skin analysis and product recommendations. This consolidated endpoint returns all necessary information about the test result in a single call.
HTTP Request
GET /core/test_result/
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| test_type | Integer | Yes | Type of test to retrieve results for |
| test_id | Integer | No | Specific test ID to retrieve (defaults to most recent test) |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.get(HOST+'/core/test_result/?test_type=1', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": {
"test_id": 78,
"created_at": "2024-09-12T15:27:20.530407Z",
"skin_type": "Комбинированная",
"skin_state": "Проблемная",
"allergy": "Возрастные изменения",
"age_detected": 31,
"user_age": 22,
"face_rank": 9.2,
"shop_id": 182,
"shop_address": "Санкт-Петербург, Комендантский пр-кт, 30, корпус 1, литера А",
"skin_concerns": {
"Атрофия кожи": 0,
"Жирный блеск": 15,
"Комедоны": 0,
"Круги/мешки под глазами": 25,
"Купероз (телеангиэктазии)": 0,
"Морщины": 15,
"Папулы и пустулы при акне": 0,
"Пигментация": 5,
"Постакне": 0,
"Расширенные поры": 30,
"Розацеа (покраснение щек)": 5,
"Рубцы": 10,
"Шелушение": 5
},
"main_concerns": [
"Расширенные поры",
"Круги/мешки под глазами",
"Жирный блеск"
],
"care_routine": {
"morning": [
{"id": 22, "name": "Очищающий гель", "order": 1},
{"id": 33, "name": "Тоник", "order": 2},
{"id": 11, "name": "Сыворотка", "order": 3},
{"id": 1, "name": "Дневной крем", "order": 4},
{"id": 34, "name": "Крем для глаз", "order": 5},
{"id": 29, "name": "Солнцезащитное средство", "order": 6}
],
"evening": [
{"id": 21, "name": "Средство для снятия макияжа", "order": 1},
{"id": 22, "name": "Очищающий гель", "order": 2},
{"id": 33, "name": "Тоник", "order": 3},
{"id": 11, "name": "Сыворотка", "order": 4},
{"id": 2, "name": "Ночной крем", "order": 5},
{"id": 34, "name": "Крем для глаз", "order": 6}
],
"additional": [
{"id": 32, "name": "Маска", "order": 1},
{"id": 31, "name": "Пилинг", "order": 2},
{"id": 35, "name": "Скраб", "order": 3},
{"id": 30, "name": "Патчи", "order": 4}
]
},
"products_info": {
"2": {
"name": "Основной уход. Крем ночь",
"description": "Задача ночного ухода восстановление и обновление",
"sub_name": "Ночной уход",
"stage_type": [
"Вечерний уход"
],
"list_products": [
{
"id": 204,
"price": 1149.99,
"quantity": 1,
"shop": 182,
"code": "1000211076",
"brand": "librederm",
"price_segment": 2,
"priority": 2,
"img": "https://storage.yandexcloud.net/bsmain/media/products/1000211076.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T155210Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=9de0b839f7f4131da2aa5e68a691aba4e26fb6bffddf87dbe3bad4b4781bdc65",
"value": "50мл",
"country": "",
"category": 1,
"stage": 2,
"description": "Ночью в коже запускаются восстановительные процессы и одновременно она становится более восприимчивой к уходовым средствам. Поэтому формула ночного крема гидробаланс оптимизирована под ночные часы. В основе – комбинация двух активных компонентов – низкомолекулярной гиалуроновой кислоты и глютаминовой кислоты в высокой концентрации, которые быстро проникают в глубокие слои кожи, дарят интенсивное увлажнение и защищают от преждевременного старения. Ночной крем с легкой текстурой быстро впитывается, не забивает поры и не оставляет следов на подушке. Утром кожа выглядит свежей, отдохнувшей и сияющей. Для увлажнения в режиме 24/7 рекомендуем дополнить уход гиалуроновым кремом и сывороткой LIBREDERM.",
"name": "LIBREDERM Гиалуроновый крем Ночной гидробаланс 50мл"
}
],
"order": [4]
}
},
"brands": [
"mj care",
"limimi"
]
}
}
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает подробные результаты теста с рекомендациями |
| 401 | Неавторизован - Недействительный или отсутствующий токен |
| 404 | Не найдено - Не найден завершенный тест |
Получение текстовых результатов теста
Получение текстовых результатов и рекомендаций на основе анализа. Эта конечная точка предоставляет структурированные текстовые выводы о результатах тестирования и рекомендации по уходу в виде выбранных опций из доступных вариантов.
HTTP-запрос
GET /core/test_result_text/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| test_type | Integer | Yes | Тип теста, для которого нужно получить текстовые результаты |
| test_id | Integer | No | ID конкретного теста для получения результатов (по умолчанию используется последний тест) |
| type | String | No | Тип результатов для получения. Возможные значения: short_face, full_face (Если был пройден с test_type=1), short_hair, full_hair (Если был пройден с test_type=2), teeth, full_teeth(Если был пройден с test_type=3), tongue, full_tongue(Если был пройден с test_type=4), nails, full_nails(Если был пройден с test_type=5) |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzU3NjgwNjc3LCJpYXQiOjE3MjYxNDQ2NzcsImp0aSI6ImQ0OTUxZjE0ZTM3NzQwYjNhNWE5ZjgxMDZjMDMyN2ZjIiwidXNlcl9pZCI6NH0.tK_yVYx6m8vQL2r7k0EEl6peilAWVZqUKuzYt2hVr-g"}
response = requests.get(HOST+'/core/test_result_text/?test_type=1&type=short_face', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": [
{
"chosen_option": "Комбинированная кожа",
"available_options": ["Сухая кожа", "Нормальная кожа", "Комбинированная кожа", "Жирная кожа"],
"text_comment": "Ваш тип кожи определен как комбинированный, с жирной T-зоной и нормальной или сухой кожей на щеках. Это самый распространенный тип кожи, требующий сбалансированного ухода."
},
{
"chosen_option": "Средняя степень чувствительности",
"available_options": ["Низкая степень чувствительности", "Средняя степень чувствительности", "Высокая степень чувствительности"],
"text_comment": "Ваша кожа показывает среднюю степень чувствительности, что означает периодические покраснения или дискомфорт при использовании некоторых продуктов или воздействии внешних факторов."
},
{
"chosen_option": "Расширенные поры",
"available_options": ["Расширенные поры", "Морщины", "Пигментация", "Акне", "Купероз"],
"text_comment": "Основной проблемой вашей кожи являются расширенные поры, особенно в T-зоне. Это связано с повышенной активностью сальных желез и требует регулярного очищения и правильно подобранных средств."
},
{
"chosen_option": "Умеренный фотостарение",
"available_options": ["Отсутствие признаков фотостарения", "Легкое фотостарение", "Умеренный фотостарение", "Выраженное фотостарение"],
"text_comment": "Анализ показал признаки умеренного фотостарения кожи, вызванного воздействием УФ-излучения. Рекомендуется использование средств с SPF и антиоксидантами для защиты и восстановления кожи."
}
]
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным |
| data | Array | Список текстовых результатов анализа |
| data[].chosen_option | String | Выбранный вариант/опция, соответствующая результату анализа |
| data[].available_options | Array | Список всех возможных вариантов для этой категории анализа |
| data[].text_comment | String | Подробное текстовое описание и пояснение к выбранному варианту |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает текстовые результаты анализа |
| 401 | Неавторизован - Недействительный или отсутствующий токен |
| 404 | Не найдено - Не найден завершенный тест или результаты для указанного типа |
Получение визуализации результатов
Получение визуализаций на основе результатов теста в зависимости от типа теста.
HTTP-запрос
GET /core/test_result_visuals/
Параметры запроса
| Parameter | Type | Required | Description |
|---|---|---|---|
| test_type | Integer | Yes | Тип теста для получения визуализаций (1-5) |
| test_id | Integer | No | ID конкретного теста для получения визуализаций (по умолчанию используется последний тест) |
| type | String | No | Тип визуализаций для получения. Возможные значения: short_face, full_face (Если был пройден с test_type=1), short_hair, full_hair (Если был пройден с test_type=2), teeth, full_teeth(Если был пройден с test_type=3), tongue, full_tongue(Если был пройден с test_type=4), nails, full_nails(Если был пройден с test_type=5) |
import requests
headers = {'J-Authorization': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
response = requests.get(HOST+'/core/test_result_visuals/?test_type=1&type=short_face', headers=headers)
Вышеуказанная команда возвращает JSON, структурированный следующим образом:
{
"result": true,
"data": [
{
"title": "Анализ кожи",
"description": "Основные проблемы, выявленные при анализе",
"image_url": "https://storage.yandexcloud.net/bsmain/user_visuals/chart_42561789.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=7a4c8b1e0f5d2a36b9e7c482d1f5a09e3b8c7d6f5a4b3c2d1e0f9a8b7c6d5e4f",
"type": "short_face"
},
{
"title": "До и После",
"description": "Сравнение состояния кожи до и после рекомендованного ухода",
"image_url": "https://storage.yandexcloud.net/bsmain/user_visuals/compare_42561789.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEeK91nbw67saGpFsUTIi7%2F20240912%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20240912T154043Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=5e4f3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3",
"type": "short_face"
}
]
}
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли запрос успешным |
| data | Array | Список объектов визуализации |
| data[].title | String | Заголовок визуализации |
| data[].description | String | Описание визуализации |
| data[].image_url | String | URL изображения визуализации (срок действия истекает через 1 час) |
| data[].type | String | Тип визуализации (short_face, full_face, hair, teeth и т.д.) |
Коды ответа
| Code | Description |
|---|---|
| 200 | Успех - Возвращает изображения визуализации |
| 401 | Неавторизован - Недействительный или отсутствующий токен |
| 404 | Не найдено - Не найден завершенный тест или визуализации |
Ассортимент
Раздел "Ассортимент" предоставляет конечные точки для управления каталогом продуктов, включая добавление новых товаров в систему. Эти endpoints позволяют интегрированным партнерам расширять базу продуктов для более точных рекомендаций.
Добавление товара
Добавление нового продукта в каталог системы. Эта конечная точка позволяет партнерам добавлять товары различных категорий для последующего использования в рекомендательной системе.
Поддерживаемые типы товаров: - type=1 (Уход за лицом) - косметические средства по уходу за кожей лица - type=2 (Макияж) - декоративная косметика и средства для макияжа
HTTP-запрос
POST /shop/products/add/
Заголовки запроса
| Header | Description |
|---|---|
| J-Authorization | Токен доступа, полученный после аутентификации. Требуются права администратора или партнера. |
| Content-Type | application/json |
Параметры запроса для type=1 (Уход за лицом)
| Parameter | Type | Required | Description |
|---|---|---|---|
| type | Integer | Yes | Тип товара (1 = уход за лицом) |
| brand | String | Yes | Название бренда (например, "Derma Expert") |
| country | String | Yes | Страна производства (например, "Франция") |
| sku | String | Yes | Уникальный артикул товара (например, "2000745821") |
| stage | String | Yes | Этап ухода (например, "Основной уход. Для области вокруг глаз") |
| value | String | Yes | Объем/количество (например, "30мл") |
| name | String | Yes | Название продукта |
| effect | String | Yes | Описание эффектов и активных компонентов |
| spec | String | Yes | Полный состав по INCI |
| additional_info | String | No | Дополнительная информация о продукте |
| how_to_use | String | Yes | Инструкция по применению |
| collection_description | String | No | Описание коллекции или линейки |
| texture | String | Yes | Текстура продукта (например, "Кремовая") |
| makeup_type_delete | String | No | Устаревшее поле (оставить пустым) |
| SPF | String | No | Уровень SPF защиты (если применимо) |
Поля ответа
| Field | Type | Description |
|---|---|---|
| result | Boolean | Указывает, был ли продукт успешно добавлен в систему |
| data | Object | Информация о добавленном продукте |
| data.product_id | Integer | Уникальный идентификатор созданного продукта в системе |
| data.message | String | Сообщение о статусе операции |
| data.sku | String | Подтверждение SKU добавленного продукта |
| data.status | String | Статус продукта (pending_review, active, rejected) |
Коды ответа
| Code | Description |
|---|---|
| 201 | Создано - Продукт успешно добавлен в каталог и ожидает модерации |
| 400 | Неверный запрос - Отсутствуют обязательные поля или неверный формат данных |
| 401 | Неавторизован - Недействительный или отсутствующий токен доступа |
| 403 | Запрещено - Недостаточно прав для добавления продуктов (требуются права партнера) |
| 409 | Конфликт - Продукт с таким SKU уже существует в системе |
| 422 | Необрабатываемая сущность - Ошибки валидации в данных продукта |
| 429 | Слишком много запросов - Превышен лимит добавления продуктов (максимум 50 продуктов в час) |
| 500 | Внутренняя ошибка сервера - Временный сбой в работе сервиса добавления продуктов |