# SEO Tools API

Программный доступ к платформе **seotoolse.ru**: запуск SEO/GEO-инструментов и контент-фабрики, получение результатов, расписания и экспорт. Тот же бэкенд, что и кабинет — данные из официальных API Яндекса и Google + AI-движок.

- **Base URL:** `https://seotoolse.ru/api`
- **Формат:** JSON (`Content-Type: application/json`), UTF-8
- **Авторизация:** Bearer-токен `sk_live_…` (см. ниже)
- **MCP:** для AI-ассистентов есть готовый MCP-сервер — см. [`../mcp-server.js`](../mcp-server.js) и раздел [MCP](#mcp).

---

## 1. Авторизация

API использует **персональный токен** формата `sk_live_<64 hex>`. Доступно с тарифа **STARTER** и выше.

### Получить токен
В кабинете: **Настройки → API → Сгенерировать токен**. Plaintext показывается **один раз** — сохраните его. Повторная генерация отзывает старый токен.

Программно (нужен JWT из логина):
```bash
curl -X POST https://seotoolse.ru/api/auth/api-token \
  -H "Authorization: Bearer <JWT>"
# → { "apiToken": "sk_live_…", "preview": "sk_live_…XXXX" }
```

### Использовать токен
Передавайте в каждом запросе:
```
Authorization: Bearer sk_live_xxxxxxxx...
```

> Токен = полный доступ к аккаунту и списанию токенов. Храните как пароль, не коммитьте в репозиторий. При утечке — перегенерируйте (старый сразу инвалидируется).

---

## 2. Модель работы

1. **Создаёте задачу** (`POST /tasks`) с типом и входными данными → получаете `taskId`, токены списываются сразу.
2. Задача проходит статусы: `QUEUED` → `PROCESSING` → `COMPLETED` (или `FAILED` — токены возвращаются).
3. **Опрашиваете** (`GET /tasks/{id}`) до терминального статуса → читаете `result`.
4. При желании — **экспорт** (`GET /export/{id}`) в CSV/XLSX или **расписание** (`POST /scheduled`).

Стоимость — в **токенах** (списываются с баланса тарифа). Цена за задачу = цена за единицу × кол-во единиц (ключей/URL), для AI-тулзов — по выбранному тиру модели.

---

## 3. Эндпоинты

### `POST /tasks` — создать задачу
**Тело:**
```json
{ "type": "SERP_TOP", "input": { "keywords": ["купить бетон"], "engine": "yandex", "region": "213" }, "projectId": "опц." }
```
**Ответ `201`:**
```json
{ "taskId": "cmq…", "type": "SERP_TOP", "status": "QUEUED", "creditsCost": 1 }
```
Ошибки: `400` (невалидный вход), `402` (не хватает токенов — `{required, available}`), `403` (тариф/модель не позволяет), `429` (лимит частоты).

### `GET /tasks/{id}` — статус и результат
```json
{ "id": "cmq…", "type": "SERP_TOP", "status": "COMPLETED",
  "progress": 100, "creditsCost": 1, "resultCount": 10,
  "result": { "items": [ … ] } }
```

### `GET /tasks?limit=10&type=SERP_TOP` — история задач
Список метаданных (без тяжёлого `result`).

### `GET /auth/me` — баланс, тариф, лимиты
```json
{ "user": { "id": "…", "email": "…", "plan": "STARTER", "credits": 5000, "apiEnabled": true } }
```

### `GET /tools` — каталог инструментов
Полный справочник. На каждый инструмент:
```json
{ "slug": "article-write", "type": "ARTICLE_WRITE", "name": "Генератор статьи",
  "category": "content", "unit": "статья", "description": "…",
  "costPer": 20, "paid": true, "comingSoon": false, "tierPriced": true,
  "models": [ { "id": "seo-lite", "label": "SEO Lite", "credits": 20 }, … ] }
```
- `type` — передавайте в `POST /tasks`. `costPer` — цена за `unit` (для `tierPriced` — «от», цена тира Lite; полная сетка в `models`).
- `paid: true` — нужен STARTER+. `comingSoon: true` — инструмент в разработке (POST вернёт 400).
- Цены берутся из тарифной сетки в реальном времени — всегда актуальны.

### `POST /scheduled` — расписание (cron)
```json
{ "name": "Позиции каждый день", "type": "POSITION_CHECK",
  "input": { "domain": "site.ru", "keywords": ["…"] },
  "cronPattern": "0 9 * * *", "timezone": "Europe/Moscow" }
```
### `GET /scheduled` — список расписаний

### `GET /export/{id}?format=csv` — экспорт результата
`format`: `csv` | `xlsx` | `json`.

---

## 4. Справочник типов задач

Типы передаются в `type` (UPPER_SNAKE_CASE). Цены — в токенах за единицу (актуальные на момент написания; источник правды — `GET /tools` и тарифная сетка).

### SERP / выдача
| type | вход | цена | что делает |
|---|---|---|---|
| `SERP_TOP` | keywords[], engine, region, depth | 1 (depth>10 → 5) | ТОП-10/50/100 Яндекс/Google |
| `POSITION_CHECK` | keywords[], domain | 2 | позиции домена |
| `SERP_FEATURES` | keywords[] | 2 | колдунщики (карты/видео/маркет) |
| `PAA_PARSE` | keywords[] | 2 | «Люди также спрашивают» |
| `FEATURED_SNIPPETS` | keywords[] | 2 | быстрые ответы Google |
| `YANDEX_DIRECT_ADS` | keywords[] | 2 | объявления Директа |

### Ключевые слова
| type | вход | цена | что делает |
|---|---|---|---|
| `KEYWORD_CLUSTER` | keywords[] | 1.5 | кластеризация по выдаче |
| `KEYWORD_FREQUENCY` | keywords[], mode | 1 (seasonality → 3) | частотность (Я.Директ) |
| `KEYWORD_SUGGEST` | keywords[] | 1 | поисковые подсказки |
| `SEMANTIC_CORE` | keywords[] | 5 | сем. ядро через конкурентов |

### Анализ
| type | вход | цена | что делает |
|---|---|---|---|
| `META_PARSER` | urls[] | 1 | Title/Description/H1-H6 |
| `INDEXATION_CHECK` | urls[] | 1.5 | индексация в Я/G |
| `SITE_STRUCTURE` | url | 3 | структура по sitemap |
| `YQI_CHECK` | domains[] | 1 | ИКС Яндекса |
| `WHOIS_CHECK` | domains[] | 1 | данные домена |
| `COPYWRITING_BRIEF` | keywords[] | 2 | ТЗ по ТОП-10 |

### GEO / готовность к AI-поиску
| type | вход | цена | что делает |
|---|---|---|---|
| `GEO_CHECK` | domain, keywords[] | 250/запрос | упоминание сайта в Яндекс Нейро |
| `GEO_AUDIT` | url, aiSummary? | 8 | комплексный GEO-аудит |
| `AI_READINESS` | url | 5 | готовность к ИИ-поиску /100 |
| `AI_CRAWLER_ACCESS` | url | 1 | доступ ИИ-краулерам (robots.txt) |
| `GEO_CONTENT_SCORE` | url | 5 | цитируемость контента в ИИ /100 |
| `LLMS_GENERATE` | url, aiDescriptions? | 3 | генератор llms.txt |

### AI-инструменты (выбор тира модели)
Поле `input.model`: `seo-lite` (20) · `seo-midl` (40) · `seo-pro` (80) · `seo-pro-plus` (150). Цена = тиру. Доступны со **STARTER**.

| type | вход | что делает |
|---|---|---|
| `AI_META_GEN` | keywords[] \| url | Title/Description/H1 |
| `AI_INTENT` | keywords[] | тип интента |
| `AI_FAQ` | topic \| keywords[] | вопросы-ответы |
| `AI_LSI` | keyword \| keywords[] | LSI-слова |
| `AI_REWRITE` | text | рерайт |
| `AI_CONTENT_PLAN` | topic | контент-план |
| `AI_EXPAND` / `AI_SHORTEN` | text | расширить / сократить |

### Контент-фабрика
| type | вход | цена | что делает |
|---|---|---|---|
| `CONTENT_BRIEF` | query/topic, region?, template?, aiOutline? | 15 | план статьи: H2/H3 + вопросы + сущности + объём |
| `AI_VISIBILITY` | domain, keywords[] | 250/запрос | монитор AI-видимости: Share of Voice + конкуренты в Нейро |
| `ARTICLE_WRITE` | topic, keywords?, template?, outline?, wordCount?, model | по тиру | готовая SEO-статья в Markdown (H1/H2/FAQ) |

`template` (для CONTENT_BRIEF/ARTICLE_WRITE): `guide` · `howto` · `comparison` · `review` · `listicle` · `problem` · `explainer` · `product`.
Бренд-факты/голос подмешиваются автоматически, если задача привязана к проекту (`projectId`, поля проекта `brandKnowledge`/`brandVoice`).

---

## 5. Пример: от ключа до статьи

```bash
API=https://seotoolse.ru/api
TOK="Authorization: Bearer sk_live_…"

# 1. План статьи
BRIEF=$(curl -s -X POST $API/tasks -H "$TOK" -H 'Content-Type: application/json' \
  -d '{"type":"CONTENT_BRIEF","input":{"query":"как выбрать бетонный завод","aiOutline":true}}')
ID=$(echo "$BRIEF" | jq -r .taskId)

# 2. Дождаться результата
until [ "$(curl -s $API/tasks/$ID -H "$TOK" | jq -r .status)" = "COMPLETED" ]; do sleep 3; done

# 3. Сгенерировать статью
curl -s -X POST $API/tasks -H "$TOK" -H 'Content-Type: application/json' \
  -d '{"type":"ARTICLE_WRITE","input":{"topic":"как выбрать бетонный завод","model":"seo-pro","wordCount":1800}}'
```

---

## 6. Ошибки
| HTTP | значение |
|---|---|
| 400 | невалидный вход (поле обязательно/формат) |
| 401 | нет/неверный токен |
| 402 | не хватает токенов (`{required, available}`) |
| 403 | тариф/модель/доступ не позволяет (`{requiredPlan}`) |
| 429 | превышен лимит частоты или параллельных задач |
| 5xx | ошибка сервера — задача `FAILED`, токены возвращаются |

---

## MCP

Готовый MCP-сервер для Claude Code / Claude Desktop / Cursor — [`mcp-server.js`](../mcp-server.js). Даёт инструменты `seo_create_task`, `seo_get_task`, `seo_list_tasks`, `seo_check_credits`, `seo_list_tools`, `seo_create_schedule`, `seo_list_schedules`, `seo_export_task`. Конфиг — [`mcp-config-example.json`](../mcp-config-example.json):

```json
{
  "mcpServers": {
    "seo-tools": {
      "command": "node",
      "args": ["/абсолютный/путь/mcp-server.js"],
      "env": { "SEO_API_URL": "https://seotoolse.ru/api", "SEO_API_TOKEN": "sk_live_…" }
    }
  }
}
```
