# API Документация: Маркетинговый анализ (Frontend/AI Agent) ## Базовый URL ``` https://api.konturai.kz ``` ## Обзор API для генерации маркетингового анализа на основе данных о бизнесе. Процесс состоит из двух этапов: 1. **Запуск анализа** - создание задачи и начало асинхронной обработки 2. **Получение результатов** - проверка статуса и получение готового отчета Анализ выполняется асинхронно и занимает примерно 5-10 минут. --- ## Эндпоинты ### 1. Запуск маркетингового анализа **POST** `/api/marketing/analysis/start` Создает новую задачу на генерацию маркетингового анализа и запускает асинхронную обработку. #### Заголовки запроса ``` Content-Type: application/json ``` #### Тело запроса (JSON) | Поле | Тип | Обязательный | Описание | Пример значения | | ---------------- | ------ | ------------ | ------------------------------ | -------------------------------- | | `product` | string | ✅ | Название продукта или услуги | "Веб-разработка" | | `location` | string | ✅ | Географическая локация работы | "Алматы, Казахстан" | | `client` | string | ✅ | Тип целевой аудитории | "B2B клиенты" | | `differentiator` | string | ✅ | Уникальные особенности бизнеса | "Быстрая разработка за 2 недели" | #### Валидация полей **`product`** (string, обязательное) - Минимальная длина: 3 символа - Максимальная длина: 200 символов - Разрешены: буквы, цифры, пробелы, дефисы, запятые **`location`** (string, обязательное) - Минимальная длина: 2 символа - Максимальная длина: 150 символов - Разрешены: буквы, цифры, пробелы, запятые, дефисы **`client`** (string, обязательное) - Допустимые значения (точно): - `"B2B клиенты"` - `"B2C клиенты"` - `"Частные лица"` - `"Корпорации"` - `"Малый бизнес"` **`differentiator`** (string, обязательное) - Минимальная длина: 10 символов - Максимальная длина: 500 символов - Разрешены любые символы #### Пример запроса ```json { "product": "Разработка мобильных приложений", "location": "Нур-Султан, Казахстан", "client": "B2B клиенты", "differentiator": "Специализируемся на быстрой разработке MVP за 4 недели с использованием современных технологий" } ``` #### Пример успешного ответа (200 OK) ```json { "success": true, "message": "Анализ запущен успешно", "data": { "analysisId": "507f1f77bcf86cd799439011", "status": "processing", "estimatedCompletionTime": "2025-01-20T15:38:00", "message": "Анализ запущен успешно. Результаты будут готовы в течение 5-10 минут." } } ``` #### Структура ответа | Поле | Тип | Описание | | ------------------------------ | ------- | --------------------------------------------------------- | | `success` | boolean | Флаг успешности операции | | `message` | string | Сообщение о результате операции | | `data.analysisId` | string | Уникальный идентификатор анализа (MongoDB ObjectId) | | `data.status` | string | Статус анализа: `"processing"` | | `data.estimatedCompletionTime` | string | ISO 8601 дата/время ожидаемого завершения (LocalDateTime) | | `data.message` | string | Информационное сообщение для пользователя | #### Пример ошибки валидации (400 Bad Request) ```json { "success": false, "message": "Ошибка валидации", "error": { "code": "VALIDATION_ERROR", "message": "Ошибка валидации входных данных", "details": { "product": "Поле 'product' должно содержать от 3 до 200 символов", "client": "Поле 'client' должно быть одним из: B2B клиенты, B2C клиенты, Частные лица, Корпорации, Малый бизнес" } } } ``` --- ### 2. Получение результата анализа **GET** `/api/marketing/analysis/{analysisId}` Возвращает статус и результаты анализа по идентификатору. #### Параметры пути | Параметр | Тип | Описание | | ------------ | ------ | --------------------- | | `analysisId` | string | Идентификатор анализа | #### Пример запроса ``` GET /api/marketing/analysis/507f1f77bcf86cd799439011 ``` #### Пример ответа (когда анализ завершен - 200 OK) ```json { "success": true, "message": "Операция выполнена успешно", "data": { "analysisId": "507f1f77bcf86cd799439011", "status": "completed", "createdAt": "2025-01-20T15:30:00", "completedAt": "2025-01-20T15:38:00", "report": { "summary": "Краткое резюме анализа...", "targetAudience": { "description": "Описание целевой аудитории...", "channels": ["Instagram", "LinkedIn", "Telegram"] }, "recommendations": ["Рекомендация 1", "Рекомендация 2", "Рекомендация 3"], "strategy": { "duration": "2 недели", "channels": ["Instagram", "Telegram", "21MC"], "contentTypes": ["посты", "сторис", "баннеры"] }, "pdfUrl": "/api/marketing/analysis/507f1f77bcf86cd799439011/download" } } } ``` #### Пример ответа (когда анализ еще обрабатывается - 200 OK) ```json { "success": true, "message": "Операция выполнена успешно", "data": { "analysisId": "507f1f77bcf86cd799439011", "status": "processing", "createdAt": "2025-01-20T15:30:00", "completedAt": null, "report": null } } ``` #### Статусы анализа | Статус | Описание | | ------------ | ----------------------------- | | `queued` | Запрос в очереди на обработку | | `processing` | Анализ выполняется | | `completed` | Анализ завершен успешно | | `failed` | Анализ завершился с ошибкой | #### Структура ответа | Поле | Тип | Описание | | ---------------------------------------- | ------- | ------------------------------------------------------ | | `success` | boolean | Флаг успешности операции | | `message` | string | Сообщение о результате операции | | `data.analysisId` | string | Уникальный идентификатор анализа | | `data.status` | string | Статус анализа | | `data.createdAt` | string | ISO 8601 дата/время создания | | `data.completedAt` | string | ISO 8601 дата/время завершения (null если не завершен) | | `data.report` | object | Объект с результатами (null если не завершен) | | `data.report.summary` | string | Краткое резюме анализа | | `data.report.targetAudience` | object | Информация о целевой аудитории | | `data.report.targetAudience.description` | string | Описание целевой аудитории | | `data.report.targetAudience.channels` | array | Список рекомендуемых каналов | | `data.report.recommendations` | array | Список рекомендаций (массив строк) | | `data.report.strategy` | object | Маркетинговая стратегия | | `data.report.strategy.duration` | string | Длительность кампании (например, "2 недели") | | `data.report.strategy.channels` | array | Каналы коммуникации (массив строк) | | `data.report.strategy.contentTypes` | array | Типы контента (массив строк) | | `data.report.pdfUrl` | string | URL для скачивания PDF отчета | #### Пример ошибки (404 Not Found) ```json { "success": false, "message": "Анализ не найден", "error": { "code": "NOT_FOUND", "message": "Анализ с указанным ID не найден" } } ``` --- ### 3. Скачивание PDF отчета **GET** `/api/marketing/analysis/{analysisId}/download` Возвращает PDF файл с полным маркетинговым отчетом. #### Параметры пути | Параметр | Тип | Описание | | ------------ | ------ | --------------------- | | `analysisId` | string | Идентификатор анализа | #### Пример запроса ``` GET /api/marketing/analysis/507f1f77bcf86cd799439011/download ``` #### Успешный ответ (200 OK) - **Content-Type**: `application/pdf` - **Content-Disposition**: `attachment; filename="marketing_analysis_507f1f77bcf86cd799439011_1234567890.pdf"` - **Body**: Бинарные данные PDF файла #### Ошибки - **404 Not Found** - Анализ не найден или PDF еще не сгенерирован - **500 Internal Server Error** - Ошибка при получении файла --- ## Обработка ошибок ### Коды ошибок | Код | HTTP статус | Описание | | ----------------------- | ----------- | ------------------------------- | | `VALIDATION_ERROR` | 400 | Ошибка валидации входных данных | | `NOT_FOUND` | 404 | Ресурс не найден | | `INTERNAL_SERVER_ERROR` | 500 | Внутренняя ошибка сервера | ### Формат ошибки ```json { "success": false, "message": "Описание ошибки", "error": { "code": "ERROR_CODE", "message": "Детальное сообщение об ошибке", "details": { "field1": "Сообщение об ошибке для поля 1", "field2": "Сообщение об ошибке для поля 2" } } } ``` **Примечание**: Поле `details` присутствует только для ошибок валидации (`VALIDATION_ERROR`). --- ## Примеры использования ### JavaScript/TypeScript (Fetch API) #### Запуск анализа ```javascript async function startMarketingAnalysis(data) { const response = await fetch( 'https://api.konturai.kz/api/marketing/analysis/start', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ product: 'Разработка мобильных приложений', location: 'Нур-Султан, Казахстан', client: 'B2B клиенты', differentiator: 'Специализируемся на быстрой разработке MVP за 4 недели', }), } ); const result = await response.json(); if (result.success) { console.log('Analysis ID:', result.data.analysisId); return result.data.analysisId; } else { console.error('Error:', result.error); throw new Error(result.error.message); } } ``` #### Проверка статуса и получение результата ```javascript async function getAnalysisResult(analysisId) { const response = await fetch( `https://api.konturai.kz/api/marketing/analysis/${analysisId}` ); const result = await response.json(); if (result.success) { const { status, report } = result.data; if (status === 'completed' && report) { console.log('Analysis completed!'); console.log('Summary:', report.summary); console.log('Recommendations:', report.recommendations); return report; } else if (status === 'processing') { console.log('Analysis is still processing...'); return null; // Повторить запрос позже } else if (status === 'failed') { throw new Error('Analysis failed'); } } else { throw new Error(result.error.message); } } ``` #### Полный цикл с polling ```javascript async function waitForAnalysisCompletion( analysisId, maxAttempts = 60, intervalMs = 10000 ) { for (let i = 0; i < maxAttempts; i++) { const result = await getAnalysisResult(analysisId); if (result) { return result; // Анализ завершен } // Ждем перед следующей проверкой await new Promise((resolve) => setTimeout(resolve, intervalMs)); } throw new Error('Analysis timeout'); } // Использование async function runFullAnalysis() { try { // 1. Запускаем анализ const analysisId = await startMarketingAnalysis({ product: 'Веб-разработка', location: 'Алматы, Казахстан', client: 'B2B клиенты', differentiator: 'Быстрая разработка за 2 недели', }); console.log(`Analysis started: ${analysisId}`); // 2. Ждем завершения (проверяем каждые 10 секунд, максимум 10 минут) const report = await waitForAnalysisCompletion(analysisId, 60, 10000); // 3. Используем результаты console.log('Report summary:', report.summary); console.log('Channels:', report.targetAudience.channels); console.log('PDF URL:', report.pdfUrl); return report; } catch (error) { console.error('Error:', error); } } ``` #### Скачивание PDF ```javascript async function downloadPdf(analysisId) { const response = await fetch( `https://api.konturai.kz/api/marketing/analysis/${analysisId}/download` ); if (!response.ok) { throw new Error('Failed to download PDF'); } const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `marketing_analysis_${analysisId}.pdf`; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); } ``` ### Python ```python import requests import time BASE_URL = "https://api.konturai.kz" def start_analysis(product, location, client, differentiator): response = requests.post( f"{BASE_URL}/api/marketing/analysis/start", json={ "product": product, "location": location, "client": client, "differentiator": differentiator } ) response.raise_for_status() data = response.json() if data["success"]: return data["data"]["analysisId"] else: raise Exception(data["error"]["message"]) def get_analysis_result(analysis_id): response = requests.get( f"{BASE_URL}/api/marketing/analysis/{analysis_id}" ) response.raise_for_status() return response.json()["data"] def wait_for_completion(analysis_id, max_attempts=60, interval=10): for _ in range(max_attempts): result = get_analysis_result(analysis_id) if result["status"] == "completed": return result["report"] elif result["status"] == "failed": raise Exception("Analysis failed") time.sleep(interval) raise Exception("Analysis timeout") # Использование analysis_id = start_analysis( product="Разработка мобильных приложений", location="Нур-Султан, Казахстан", client="B2B клиенты", differentiator="Быстрая разработка MVP за 4 недели" ) print(f"Analysis started: {analysis_id}") report = wait_for_completion(analysis_id) print(f"Summary: {report['summary']}") print(f"Channels: {report['targetAudience']['channels']}") ``` --- ## Рекомендации по интеграции ### 1. Polling стратегия Рекомендуется проверять статус анализа каждые 10-15 секунд. Максимальное время ожидания - 10-15 минут. ### 2. Обработка ошибок Всегда проверяйте поле `success` в ответе и обрабатывайте ошибки соответствующим образом. ### 3. Валидация на клиенте Перед отправкой запроса рекомендуется валидировать данные на клиенте: - Проверка длины полей - Проверка допустимых значений для `client` - Проверка обязательных полей ### 4. UX рекомендации - Показывайте индикатор загрузки во время обработки - Отображайте примерное время завершения - Предоставьте возможность отменить ожидание и проверить результат позже - Сохраняйте `analysisId` для последующей проверки статуса ### 5. Кэширование После получения результатов можно кэшировать их локально, используя `analysisId` как ключ. --- ## Примечания 1. **Формат даты**: Все даты возвращаются в формате ISO 8601 без timezone (LocalDateTime) 2. **Идентификаторы**: Используются MongoDB ObjectId (24 символа hex) 3. **Асинхронность**: Анализ выполняется асинхронно, не блокируя запрос 4. **Таймауты**: Рекомендуется устанавливать таймаут на запросы (минимум 30 секунд для запуска анализа) 5. **Rate Limiting**: В будущем может быть добавлено ограничение на количество запросов --- ## Поддержка При возникновении проблем с API обращайтесь в техническую поддержку с указанием: - `analysisId` (если есть) - Время запроса - Описание проблемы - Код ошибки (если есть)