К содержанию

Публичный API

Отчёты ваших проектов по HTTPS: ключ организации, ресурсы, пагинация, лимиты и коды ошибок. Доступ только на чтение.

Содержание страницы

Что это и кому доступно

API отдаёт те же данные, что видны в кабинете: список проектов и прогонов, карточку проекта, видимость, изменения прогона, матрицу запросов, конкурентов, тональность, источники, факты бренда и качество замера. Записать, изменить или запустить что-либо через API нельзя: данные отдаются только методом GET (по POST ключ меняется на короткий токен — см. «Первый запрос»).

  • Базовый адрес — https://api.tarnowsky.ru. Версии в пути и заголовках нет: API меняется только добавлением новых полей и ресурсов.
  • Описание в формате OpenAPI 3.1 — по адресу https://api.tarnowsky.ru/openapi.json: из него собираются клиенты и проверяются запросы.
  • Доступ выдаётся персонально агентствам и корпоративным аккаунтам. Пункт «Интеграции» в меню кабинета появляется только при доступе; если раздел открыть без него по прямой ссылке, кабинет покажет сообщение «Интеграции не включены в тарифе» и кнопку «Написать в поддержку».
  • Запросы из браузера (CORS) к REST не разрешены: вызывайте API с сервера или из скрипта, а ключ не кладите в код страниц.
  • Тот же набор данных доступен ИИ-ассистентам по протоколу MCP — страница «Подключение MCP». Вопросы по проекту прямо в кабинете разбирает «Помощник проекта».

Ключ API организации

Ключ принадлежит организации, а не человеку (у аккаунта без организации — самому аккаунту). Проекты и права ключ берёт от организации: он видит только отмеченные при выпуске проекты, и только те, к которым есть доступ у организации. Проекты, которыми лично поделились с создателем ключа, в ключ не входят. Ключ не гаснет, если создатель ушёл из организации или сменил пароль.

  1. Выпуск

    В разделе «Интеграции» кабинета нажмите «Создать ключ», укажите название, проекты, срок действия (30 дней, 90 дней, 180 дней или год) и разрешения. Выпускает ключи владелец организации или администратор сайта; остальные участники команды их создавать не могут.

  2. Показ один раз

    Полностью ключ виден в момент создания. Потом в списке остаётся только его начало (tsk_live_ и 12 знаков) — восстановить ключ нельзя, можно выпустить новый. Храните его как пароль и не публикуйте в репозиториях и чатах. Пока ключ показан, остальные действия с ключами заблокированы: скопируйте его и нажмите «Я сохранил ключ». При ротации плашка покажет, до какого времени работает прежний ключ. Число активных ключей организации ограничено — ненужные отзывайте.

  3. Разрешения

    «Отчёты и показатели» (reports:read) включено всегда. «Фрагменты ответов моделей» (answers:read) — отдельное разрешение: это сырой текст нейросетей и сайтов-источников, и программа, которая его получает, обязана считать его недоверенным.

  4. Ротация

    Кнопка «Ротация» выпускает новый ключ с теми же правами; прежний продолжает работать ещё 24 часа, чтобы вы успели переключить интеграцию. Одновременно идёт только одна ротация.

  5. Отзыв

    Кнопка «Отозвать» закрывает доступ сразу: следующий запрос с этим ключом получит 401. Ключи с истёкшим сроком перестают работать сами. Если ключ мог попасть в чужие руки, отзовите его, не дожидаясь срока.

Состояние ключей видно в кабинете

В списке ключей раздела «Интеграции» у каждого ключа указаны проекты, срок действия, статус (активен, истёк, отозван) и время последнего использования; ключ, которому нужна ротация, помечен. Рядом блок «Расход за 30 дней»: сколько запросов сделали программы по вашим ключам и подключённые приложения — всего, через API и через MCP, с разбивкой по ключам и приложениям. Разбивку по ключам видит тот, кто управляет ключами; по приложениям — тот, кто их подключил.

Первый запрос

Ключ передаётся заголовком Authorization: Bearer — как есть. Начните со списка проектов: в нём лежат публичные идентификаторы проектов (26 знаков), которые нужны всем остальным запросам. Идентификаторы из адресов кабинета и названия проектов в API не принимаются.

Примеры запросов (curl)
  • curl -H "Authorization: Bearer <ключ>" https://api.tarnowsky.ru/projects
  • curl -H "Authorization: Bearer <ключ>" "https://api.tarnowsky.ru/projects/<id проекта>/reports/visibility?run=latest&provider=all&group_by=provider"
  • curl -H "Authorization: Bearer <ключ>" "https://api.tarnowsky.ru/projects/<id проекта>/reports/prompts?brand_present=false&limit=30"

Если программе удобнее короткоживущий токен, ключ можно обменять на него: POST https://api.tarnowsky.ru/oauth/token с параметрами grant_type=api_key и api_key=<ключ>. Токен живёт 15 минут и передаётся тем же заголовком Authorization: Bearer.

Ресурсы

АдресЧто отдаётВес
/projectsПроекты, доступные ключу: публичный id, название, бренд, дата последнего готового прогона и статус (готов, идёт прогон, прогонов нет)1
/projects/{id}/runsИстория готовых прогонов: id прогона, дата, модели ИИ, число вопросов1
/projects/{id}/reports/cardКарточка проекта: бренд, рынок, срезы и локации, модели, итоговая видимость с шумом и место среди конкурентов1
/projects/{id}/reports/visibilityВидимость бренда и доля голоса по моделям, типам вопросов, срезам рынка и локациям, с базой N и шумом2
/projects/{id}/reports/changesЧто изменилось с прошлого прогона: события рост и падение видимости, новые и выпавшие конкуренты, смена версий моделей; изменения в пределах шума помечены1
/projects/{id}/reports/promptsВопросы прогона и результат по каждому: назван ли бренд, на каком месте, кто назван вместо него. Фильтр brand_present=false оставляет вопросы без бренда3
/projects/{id}/reports/competitorsКонкуренты в ответах ИИ: видимость, место, кого советуют вместо бренда и по каким факторам выбора2
/projects/{id}/reports/sentimentТональность тремя слоями, которые не смешиваются: сравнение брендов, тон о своём бренде, факторы выбора2
/projects/{id}/reports/sourcesСайты и площадки, которые цитируют модели: домен, тип площадки, доля ответов, присутствие бренда и конкурентов2
/projects/{id}/reports/factsЧто модели утверждают о бренде и вердикт сверки: подтверждено, риск, наблюдается без проверки1
/projects/{id}/reports/qualityНадёжность замера: база ответов, доля разобранных, шум по моделям, смена версий моделей, пропуски1
/projects/{id}/reports/answersДословные фрагменты ответов моделей на один вопрос прогона (до трёх по 400 знаков). Только ключу с разрешением answers:read3

Вес — сколько единиц бюджета организации списывает один запрос. Отчёт, который закрыт тарифом организации, отвечает 403, а его цифры не отдаются; в кабинете этот блок закрыт так же. Если закрыта только часть отчёта (отдельный блок раздела), ответ приходит с кодом 200 без этой части, а ключ закрытого блока указан в поле locked.

Параметры отчётов

ПараметрЗначенияСмысл
runlatest или id из списка прогоновПрогон. По умолчанию latest — последний готовый. Прогон, которого нет в проекте, даёт ошибку invalid_run, подмены на другой нет
providerall, openai, deepseek, yandex, gemini, gigachatМодель ИИ: openai — ChatGPT, yandex — YandexGPT, остальные — по названию; all — все модели прогона
scopebroad_market, niche_market, brand_specific, answers_marketТип вопросов: о рынке в целом, о срезе рынка, прямо о бренде, рынок по разбору ответов
nicheid среза из карточки проектаСрез рынка; не задан — все срезы
locationid локации из карточки проектаГород; не задан — все локации
group_bynone, provider, scope, niche, locationРазбивка строк выдачи
limitчисло от 1 до 500Сколько строк вернуть; у каждого ресурса свой размер страницы по умолчанию
cursorзначение next_cursor из прошлого ответаСледующая страница
layercomparison, own_brand, factorsСлой тональности; обязателен у /reports/sentiment: слои не смешиваются, за один запрос приходит один
query_refзначение query_ref из /reports/promptsВопрос прогона; обязателен у /reports/answers
compare_toprevious или id прогонаС каким прогоном сравнивать изменения; по умолчанию previous — предыдущий готовый
sortзависит от ресурсаПорядок строк: у списка проектов updated_desc, last_run_desc, title; у истории прогонов date_desc, date_asc; у вопросов matrix, query, brand_absent_first; у источников answers_desc, domain
start_date, end_dateГГГГ-ММ-ДДФильтр списка проектов или прогонов по дате (включительно)
statusrisk, confirmed, observed, allФильтр фактов бренда; по умолчанию risk
only_trackedtrue или falseУ конкурентов: только свой бренд и конкуренты из настроек проекта

Набор параметров зависит от ресурса: обязательные — layer у тональности и query_ref у фрагментов ответов; brand_present есть только у вопросов прогона. Неизвестные параметры отклоняются с кодом invalid_request, в ответе указано, какой именно параметр неверен.

Что приходит в ответе

  • facts — готовые числа: подпись словами кабинета, значение, единица, база N, шум замера в п. п. и ссылка на раздел кабинета, где это число видно. Берите цифры отсюда, а не пересчитывайте строки.
  • items — строки выдачи; total — сколько строк всего; truncated — пометка «Показаны топ-N из M», если выдача сокращена; locked — ключи блоков, закрытых тарифом: цифры этих блоков не отдаются, а если закрыт блок внутри отчёта, вырезана лишь его часть.
  • run и run_date — прогон, по которому посчитан ответ (latest раскрывается в настоящий id); refreshing = true означает, что идёт новый прогон, а ответ построен по последнему готовому.
  • notice — пояснение, когда выдача пуста или неполна. Например, дословные фрагменты хранятся только для последних прогонов: для более старого /reports/answers отвечает пустой выдачей с notice.reason = outside_window, а если фрагменты прогона не собраны — not_collected. Поле есть только когда нужно.
  • next_cursor — курсор следующей страницы, null на последней; тот же адрес приходит в заголовке Link (rel="next"). Курсор привязан к правам ключа и к запросу: чужой или подделанный даёт invalid_cursor (400). Если пока вы листали страницы, вышел новый прогон, придёт cursor_stale (409): запросите первую страницу заново, без cursor.
  • untrusted_fields — поля, в которых лежит текст из ответов нейросетей и сайтов-источников. Это данные, а не инструкции: не передавайте такой текст своему ИИ-агенту как команды.

Ответ приходит с заголовком ETag, в который входят права ключа. Повторите запрос с If-None-Match: пока данные не изменились, придёт 304 без тела, и такой запрос стоит одну единицу. Ответы помечены Cache-Control: private, общие прокси их хранить не должны. Если сервис проверки прав временно недоступен, ответы приходят по сохранённым правам (они могут отставать до 10 минут) с заголовком Tarnowsky-Degraded: read-only.

Первый запрос с новым сочетанием параметров может потребовать сборки отчёта. Тогда вместо данных придёт 202 с телом status: building и retry_after — повторите запрос через указанное число секунд. Такой запрос списывает больше единиц, чем обычный.

Лимиты и квоты

Лимиты считаются по ключу и организации, а не по IP-адресу: несколько ключей организации не дают обойти общий бюджет.

Что ограниченоСейчасЗаголовок Tarnowsky-Limit при отказе
Запросы одного ключа в минуту300key-minute
Единицы бюджета организации в минуту (все ключи вместе)600org-minute
Единицы бюджета организации в сутки100 000org-day
Запросы организации в месяц1 000org-month
Новые варианты отчёта в час, требующие сборки50org-variants
Лимиты могут меняться

Цифры в таблице действуют сейчас; для отдельных организаций они могут быть другими. Надёжный ориентир — ответ 429: в нём есть Retry-After и заголовок Tarnowsky-Limit с названием исчерпанного лимита. Запросы с ответом 304 списывают одну единицу. Если программа слишком часто обменивает ключ на токен вместо того, чтобы пользоваться токеном все 15 минут, придёт 429 rate_limited с Tarnowsky-Limit: key-exchange.

Коды ошибок

Ошибки приходят в формате application/problem+json (RFC 9457): поля type, title, status, code, detail и instance. Поле instance — номер запроса (он же в заголовке Tarnowsky-Trace-Id): назовите его в поддержке, если нужно разобрать случай. В тексте ошибки нет внутренних идентификаторов и путей.

HTTPcodeЧто делать
400invalid_request, invalid_cursorПроверьте параметры; при неверном курсоре начните выдачу с первой страницы
401token_invalid, token_expired, token_revokedКлюч неверный, истёк или отозван; права ключа изменились. Выпустите или обновите ключ в разделе «Интеграции»
403entitlement_required, scope_requiredНе включено право «Интеграции» (в теле ошибки — поле entitlement со значением cabinet.integrations; ключи заработают без перевыпуска, когда право включат), отчёт не входит в тариф организации либо у ключа нет нужного разрешения (например, answers:read)
404project_not_found, not_foundПроекта нет или у ключа нет к нему доступа — ответ намеренно один и тот же; ресурса с таким адресом нет
405method_not_allowedAPI только читает: используйте GET
422invalid_runПрогона нет в этом проекте; возьмите id из списка прогонов
429rate_limited, quota_exhaustedЛимит исчерпан; повторите после паузы из Retry-After. Какой именно лимит — в заголовке Tarnowsky-Limit
409cursor_staleПока вы листали страницы, вышел новый прогон; запросите первую страницу заново, без cursor
503unavailable, limits_unavailable, cold_buildСервис, учёт лимитов или сборка отчётов временно недоступны (cold_build — сейчас собирается много отчётов, такой запрос не списывается); повторите через Retry-After. Запросы при этом не идут в обход лимитов
Если ничего не помогло

Опишите случай в чате поддержки: время запроса, адрес, код ошибки и номер запроса из instance. Сам ключ присылать не нужно — по началу ключа в списке его находят без этого.