Позиции и конкуренты
Один estimate/run-контур собирает позиции либо обычную Топ-10 выдачу конкурентов.
/projects/{projectId}/keywords/position-summarysemantics:readGET/projects/{projectId}/keywords/position-historysemantics:readGET/projects/{projectId}/tracking-contextspositions:readPOST/projects/{projectId}/tracking-contextspositions:runPATCH/projects/{projectId}/tracking-contexts/{contextId}positions:runPOST/projects/{projectId}/tracking-contexts/{contextId}/materializepositions:runPUT/projects/{projectId}/tracking-contexts/{contextId}/keywordspositions:runPOST/projects/{projectId}/rank-estimatespositions:runGET/projects/{projectId}/rank-runspositions:readPOST/projects/{projectId}/rank-runspositions:runGET/projects/{projectId}/jobs/{jobId}positions:readGET/projects/{projectId}/jobs/{jobId}/resultpositions:readPOST/projects/{projectId}/jobs/{jobId}/cancelpositions:runGET/projects/{projectId}/jobs/{jobId}/runtime-diagnosticspositions:readPOST/projects/{projectId}/jobs/{jobId}/retry-missingpositions:runGET/projects/{projectId}/rank-historypositions:readGET/projects/{projectId}/rank-workbench/dimension-mergespositions:readPOST/projects/{projectId}/rank-workbench/dimension-mergespositions:runPOST/projects/{projectId}/rank-workbench/dimension-merges/{mergeId}/removepositions:runPOST/projects/{projectId}/rank-workbench/positionspositions:readPOST/projects/{projectId}/rank-workbench/serppositions:readPOST/projects/{projectId}/rank-workbench/delete-dimension-historypositions:runGET/projects/{projectId}/keyword-ranks/dimensionspositions:readPOST/projects/{projectId}/keyword-ranks/comparisonpositions:readGET/projects/{projectId}/tracking-contexts/{contextId}positions:readPOST/projects/{projectId}/tracking-contexts/{contextId}/archivepositions:runPOST/projects/{projectId}/tracking-contexts/{contextId}/restorepositions:runGET/projects/{projectId}/tracking-contexts/{contextId}/keywordspositions:readPUT/projects/{projectId}/tracking-contexts/{contextId}/keywords/{keywordId}positions:runDELETE/projects/{projectId}/tracking-contexts/{contextId}/keywords/{keywordId}positions:runRead-only API для внешнего клиентского кабинета
Для витрины наподобие таблицы позиций создайте отдельный API-ключ только со scopes projects:read, semantics:read и positions:read. Ограничьте ключ нужными проектами. Такой ключ может читать семантику, папки, целевые URL, частотности, города, устройства и историю позиций, но не может запускать сборы или изменять данные.
# 1. Найти доступный проект
curl "https://api.seonorita.ru/api/v1/access" \
-H "Authorization: Bearer $SEO_API_TOKEN"
# 2. Получить дерево папок и семантику с целевыми URL
curl "https://api.seonorita.ru/api/v1/projects/<projectId>/keyword-groups" \
-H "Authorization: Bearer $SEO_API_TOKEN"
curl "https://api.seonorita.ru/api/v1/projects/<projectId>/keywords?limit=200" \
-H "Authorization: Bearer $SEO_API_TOKEN"
# 3. Получить точные срезы поисковик · город · устройство
curl "https://api.seonorita.ru/api/v1/projects/<projectId>/keyword-ranks/dimensions" \
-H "Authorization: Bearer $SEO_API_TOKEN"curl -X POST "https://api.seonorita.ru/api/v1/projects/<projectId>/rank-workbench/positions" \
-H "Authorization: Bearer $SEO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mode": "SEO",
"dimensionKey": "<key из keyword-ranks/dimensions>",
"observedFrom": "2026-06-01T00:00:00.000Z",
"observedBefore": "2026-09-17T00:00:00.000Z",
"dateLimit": 14,
"limit": 100,
"sort": "POSITION_ASC"
}'- 1Контекст
- 2Оценка
- 3Запуск
- 4Результат
Сводка позиций проекта
Главный экран читает текущие значения и отдельную append-only историю. История возвращает до 100 последних срезов; клиент может выбрать период и показать не более 30 точек без пересчёта данных.
curl "https://api.seonorita.ru/api/v1/projects/<projectId>/keywords/position-summary" \
-H "Authorization: Bearer $SEO_API_TOKEN"
curl "https://api.seonorita.ru/api/v1/projects/<projectId>/keywords/position-history" \
-H "Authorization: Bearer $SEO_API_TOKEN"
# Включить в исторические TOP-счётчики активные неотслеживаемые запросы
curl "https://api.seonorita.ru/api/v1/projects/<projectId>/keywords/position-history?includeUntracked=true" \
-H "Authorization: Bearer $SEO_API_TOKEN"1. Создать контекст
/projects/{projectId}/tracking-contextspositions:run{
"name": "Москва · Десктоп",
"isReusable": true,
"configuration": {
"searchEngine": "YANDEX",
"countryCode": "RU",
"regionCode": "213",
"regionLabel": "Москва",
"language": "ru",
"device": "DESKTOP",
"depth": 50,
"domainMatchRule": { "mode": "EXACT_HOST" },
"safeSearch": false
},
"launchProfile": {
"searchSource": "LIVE",
"includeUntracked": false,
"scope": { "mode": "ALL", "groupIds": [], "includeDescendants": false }
}
}Для создания обязателен уникальный Idempotency-Key. Для одноразового ручного запуска передайте isReusable=false: контекст сохранит неизменяемую историю, но не появится в каталоге профилей и расписаниях. GET-список возвращает только активные сохранённые профили. Для изменения передавайте ETag контекста через If-Match.
Пересчитать охват контекста
/projects/{projectId}/tracking-contexts/{contextId}/materializepositions:runПередайте пустой JSON. Сервер прочитает сохранённый охват, заново раскроет выбранные папки и их потомков, исключит удалённые и неотслеживаемые запросы согласно includeUntracked и вернёт актуальное количество. Keyword ID от клиента не принимаются. Регулярные и ручные запуски расписания выполняют этот пересчёт автоматически перед оценкой.
curl -X POST "https://api.seonorita.ru/api/v1/projects/<projectId>/tracking-contexts/<contextId>/materialize" \
-H "Authorization: Bearer $SEO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'{
"data": {
"contextId": "<contextId>",
"assignedKeywordCount": 894,
"addedKeywordCount": 12,
"removedKeywordCount": 3,
"unchangedKeywordCount": 882,
"keywordSetHash": { "algorithm": "SHA_256", "value": "..." },
"version": 5,
"changedAt": "2026-09-13T19:30:00.000Z"
},
"meta": { "requestId": "01J...", "version": 5 }
}2. Получить оценку
/projects/{projectId}/rank-estimatespositions:runcurl -X POST "https://api.seonorita.ru/api/v1/projects/<projectId>/rank-estimates" \
-H "Authorization: Bearer $SEO_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: rank-estimate:agent:2026-09-01T16:00" \
-d '{
"trackingContextId": "<contextId>",
"purpose": "POSITION_TRACKING",
"provider": "XMLSTOCK",
"searchSource": "LIVE"
}'{
"data": {
"id": "<estimateId>",
"trackingContextId": "<contextId>",
"status": "READY",
"provider": "XMLSTOCK",
"purpose": "POSITION_TRACKING",
"credentialMode": "PLATFORM_PAID",
"scope": {
"keywordCount": "2130",
"contextCount": "1",
"pairCount": "2130",
"contextVersion": 3,
"configurationVersion": 2,
"scopeHash": { "availability": "AVAILABLE", "algorithm": "SHA_256", "value": "..." }
},
"platformChargeMicro": "4260000",
"billingCurrency": "RUB",
"blockers": [],
"executionAllowed": true,
"expiresAt": "2026-09-01T16:15:00.000Z"
},
"meta": { "requestId": "01J..." }
}3. Подтвердить запуск
/projects/{projectId}/rank-runspositions:run{
"estimateId": "<estimateId>",
"confirmedPlatformChargeMicro": "4260000"
}Подтверждайте ровно platformChargeMicro из оценки. Для BYOK запуска значение равно "0". Ответ 202 содержит задание, а не готовые позиции.
{
"data": {
"id": "<jobId>",
"type": "MANUAL_RANK_CHECK",
"provider": "XMLSTOCK",
"status": "PREPARING",
"stage": "PREPARING_SCOPE",
"progress": { "current": "0", "total": "2130", "unit": "KEYWORD" },
"platformChargeMicro": "4260000",
"billingCurrency": "RUB",
"createdAt": "2026-09-01T16:01:00.000Z"
},
"meta": { "requestId": "01J..." }
}4. Получить результат
curl "https://api.seonorita.ru/api/v1/projects/<projectId>/jobs/<jobId>/result?limit=200" \
-H "Authorization: Bearer $SEO_API_TOKEN"{
"data": {
"job": { "id": "<jobId>", "status": "COMPLETED", "stage": "FINISHED" },
"rows": [
{
"sequence": 1,
"keywordId": "019...",
"keyword": "купить холодильник",
"found": true,
"position": 7,
"rankingUrl": "https://example.ru/catalog",
"pollAttempts": 3
}
],
"page": { "hasNext": true, "nextCursor": "opaque-cursor" }
},
"meta": { "requestId": "01J..." }
}5. Собрать обычную выдачу конкурентов
Используйте тот же контекст, estimate и подтверждение, но передайте purpose: "COMPETITOR_SERP". Провайдер собирает выбранную глубину Топ-10/20/30/50/100: Arsenkin запускает инструмент check-top, XMLStock — соответствующую Yandex/Google SERP-выдачу.
curl -X POST "https://api.seonorita.ru/api/v1/projects/<projectId>/rank-estimates" \
-H "Authorization: Bearer $SEO_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: competitors:estimate:batch-42" \
-d '{
"trackingContextId": "<contextId>",
"purpose": "COMPETITOR_SERP",
"saveProjectPosition": true,
"provider": "ARSENKIN",
"searchSource": "LIVE"
}'{
"data": {
"execution": { "purpose": "COMPETITOR_SERP", "depth": 30 },
"rows": [{
"keyword": "купить холодильник",
"state": "NOT_FOUND",
"serpResults": [
{
"position": 1,
"rankingUrl": "https://competitor.example/catalog",
"title": "Каталог холодильников",
"snippet": "Описание результата"
}
]
}]
}
}